@rtorcato/js-common 2.8.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +116 -0
- package/CHANGELOG.md +30 -0
- package/CONTRIBUTORS.md +5 -0
- package/README.md +71 -22
- package/dist/abortController/index.d.ts +30 -0
- package/dist/abortController/index.d.ts.map +1 -1
- package/dist/arrays/arrays.test-d.d.ts +2 -0
- package/dist/arrays/arrays.test-d.d.ts.map +1 -0
- package/dist/arrays/arrays.test-d.js +1 -0
- package/dist/arrays/index.js +1 -1
- package/dist/boolean/index.d.ts +18 -6
- package/dist/boolean/index.d.ts.map +1 -1
- package/dist/boolean/index.js +1 -1
- package/dist/chunks/chunk-5IA77ERW.js +1 -0
- package/dist/chunks/chunk-7JQSIREC.js +1 -0
- package/dist/chunks/chunk-ARW46OJS.js +1 -0
- package/dist/chunks/chunk-MFJ5XPUX.js +1 -0
- package/dist/chunks/chunk-RBXTRLWB.js +1 -0
- package/dist/cli/catalog.js +131 -0
- package/dist/cli/cli.mjs +16 -109
- package/dist/colors/index.d.ts +23 -3
- package/dist/colors/index.d.ts.map +1 -1
- package/dist/console/index.d.ts +12 -0
- package/dist/console/index.d.ts.map +1 -1
- package/dist/crypto/index.d.ts +23 -0
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/currency/index.d.ts +0 -14
- package/dist/currency/index.d.ts.map +1 -1
- package/dist/currency/index.js +1 -1
- package/dist/date/index.d.ts +16 -0
- package/dist/date/index.d.ts.map +1 -1
- package/dist/datetime/index.d.ts +21 -9
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +1 -1
- package/dist/emails/index.d.ts +22 -0
- package/dist/emails/index.d.ts.map +1 -1
- package/dist/emails/index.js +1 -1
- package/dist/env/index.d.ts +24 -0
- package/dist/env/index.d.ts.map +1 -1
- package/dist/errors/index.d.ts +30 -2
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/events/index.d.ts +25 -1
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +1 -1
- package/dist/fetch/index.d.ts +25 -0
- package/dist/fetch/index.d.ts.map +1 -1
- package/dist/file/index.d.ts +20 -0
- package/dist/file/index.d.ts.map +1 -1
- package/dist/functions/functions.test-d.d.ts +2 -0
- package/dist/functions/functions.test-d.d.ts.map +1 -0
- package/dist/functions/functions.test-d.js +1 -0
- package/dist/functions/index.d.ts +32 -2
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +1 -1
- package/dist/geometry/index.d.ts +21 -0
- package/dist/geometry/index.d.ts.map +1 -1
- package/dist/html/index.d.ts +38 -0
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +1 -1
- package/dist/i18n/index.d.ts +23 -7
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/interval/index.d.ts +15 -0
- package/dist/interval/index.d.ts.map +1 -1
- package/dist/json/index.d.ts +27 -0
- package/dist/json/index.d.ts.map +1 -1
- package/dist/logger/index.js +1 -1
- package/dist/logger/logger.d.ts +12 -2
- package/dist/logger/logger.d.ts.map +1 -1
- package/dist/logger/logger.js +1 -1
- package/dist/logging/index.d.ts +19 -0
- package/dist/logging/index.d.ts.map +1 -1
- package/dist/maps/index.d.ts +21 -0
- package/dist/maps/index.d.ts.map +1 -1
- package/dist/mime-types/index.d.ts +20 -0
- package/dist/mime-types/index.d.ts.map +1 -1
- package/dist/node/index.d.ts +0 -9
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +1 -1
- package/dist/numbers/index.d.ts +28 -12
- package/dist/numbers/index.d.ts.map +1 -1
- package/dist/numbers/index.js +1 -1
- package/dist/objects/index.d.ts +23 -0
- package/dist/objects/index.d.ts.map +1 -1
- package/dist/objects/index.js +1 -1
- package/dist/objects/objects.test-d.d.ts +2 -0
- package/dist/objects/objects.test-d.d.ts.map +1 -0
- package/dist/objects/objects.test-d.js +1 -0
- package/dist/os/index.d.ts +18 -0
- package/dist/os/index.d.ts.map +1 -1
- package/dist/process/index.d.ts +18 -0
- package/dist/process/index.d.ts.map +1 -1
- package/dist/promises/index.d.ts +29 -2
- package/dist/promises/index.d.ts.map +1 -1
- package/dist/promises/index.js +1 -1
- package/dist/promises/promises.test-d.d.ts +2 -0
- package/dist/promises/promises.test-d.d.ts.map +1 -0
- package/dist/promises/promises.test-d.js +1 -0
- package/dist/random/index.d.ts +21 -0
- package/dist/random/index.d.ts.map +1 -1
- package/dist/regex/index.d.ts +23 -0
- package/dist/regex/index.d.ts.map +1 -1
- package/dist/security/index.d.ts +36 -4
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1 -1
- package/dist/sets/index.d.ts +19 -0
- package/dist/sets/index.d.ts.map +1 -1
- package/dist/sleep/index.d.ts +20 -0
- package/dist/sleep/index.d.ts.map +1 -1
- package/dist/strings/index.d.ts +0 -52
- package/dist/strings/index.d.ts.map +1 -1
- package/dist/strings/index.js +1 -1
- package/dist/system/index.d.ts +18 -0
- package/dist/system/index.d.ts.map +1 -1
- package/dist/time/index.d.ts +23 -4
- package/dist/time/index.d.ts.map +1 -1
- package/dist/try/trycatch.d.ts +24 -0
- package/dist/try/trycatch.d.ts.map +1 -1
- package/dist/try/trycatch.test-d.d.ts +2 -0
- package/dist/try/trycatch.test-d.d.ts.map +1 -0
- package/dist/try/trycatch.test-d.js +1 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/url/index.d.ts +23 -0
- package/dist/url/index.d.ts.map +1 -1
- package/dist/url/index.js +1 -1
- package/dist/uuid/index.d.ts +10 -0
- package/dist/uuid/index.d.ts.map +1 -1
- package/dist/validation/index.d.ts +25 -0
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +1 -1
- package/package.json +25 -23
- package/dist/chunks/chunk-6J7HIWG6.js +0 -1
- package/dist/formatting/index.d.ts +0 -40
- package/dist/formatting/index.d.ts.map +0 -1
- package/dist/formatting/index.js +0 -1
- package/dist/math/index.d.ts +0 -37
- package/dist/math/index.d.ts.map +0 -1
- package/dist/math/index.js +0 -1
- package/dist/try/attempt.d.ts +0 -8
- package/dist/try/attempt.d.ts.map +0 -1
- package/dist/try/attempt.js +0 -1
package/AGENTS.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<!-- Generated from skills/js-common/SKILL.md by scripts/sync-agents.mjs — do not edit by hand; run `pnpm sync:agents`. -->
|
|
2
|
+
|
|
3
|
+
# Using @rtorcato/js-common
|
|
4
|
+
|
|
5
|
+
`@rtorcato/js-common` is a tree-shakeable, ESM-only utility library for Node.js >= 22 (TypeScript-first, JSDoc on every public API). One subpath export per concern — 44 of them. The package root is intentionally empty.
|
|
6
|
+
|
|
7
|
+
## Rules
|
|
8
|
+
|
|
9
|
+
1. **Import from the subpath, never the package root.** The root export has no runtime code at all, so a root import gets you nothing.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
// ✅ do
|
|
13
|
+
import { slugify } from '@rtorcato/js-common/strings'
|
|
14
|
+
// ❌ don't — the root export is empty by design
|
|
15
|
+
import { slugify } from '@rtorcato/js-common'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. **Every export name has exactly one home.** No name is exported from two modules, so the module → exports table below is the only lookup you need. These pairs still read alike — check which one you want:
|
|
19
|
+
|
|
20
|
+
| Looks like | Actually |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `functions.once` vs `events.onceEvent` | `once(fn)` memoises a call; `onceEvent(target, type)` awaits a DOM event |
|
|
23
|
+
| `logger` vs `logging` | `logger` is one configured pino instance; `logging` is `console` helpers with no runtime deps |
|
|
24
|
+
| `try.tryCatch` vs `errors.tryWithFallback` | Result object vs swallow-and-fall-back — see rule 3 |
|
|
25
|
+
| `date.formatDate` vs `datetime.formatDateTimeLocal` | a UTC calendar day vs a local instant |
|
|
26
|
+
|
|
27
|
+
Where two modules used to ship the same name, the loser was deleted rather than aliased — [MODULE-BOUNDARIES.md](https://github.com/rtorcato/js-common/blob/main/MODULE-BOUNDARIES.md) records which side won and why.
|
|
28
|
+
|
|
29
|
+
3. **Three different error idioms — don't mix them up.**
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// Result object — preferred for new code
|
|
33
|
+
import { tryCatch } from '@rtorcato/js-common/try'
|
|
34
|
+
const { data, error } = await tryCatch(() => fetchData())
|
|
35
|
+
|
|
36
|
+
// Go-style tuple: [error, data] — error FIRST
|
|
37
|
+
import { to } from '@rtorcato/js-common/promises'
|
|
38
|
+
const [err, value] = await to(fetchData())
|
|
39
|
+
|
|
40
|
+
// Swallows the error and returns a fallback — only when the fallback is genuinely safe
|
|
41
|
+
import { tryWithFallback } from '@rtorcato/js-common/errors'
|
|
42
|
+
const rows = await tryWithFallback(() => fetchRows(), [])
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`tryCatch` in `errors` was renamed to `tryWithFallback` in 2.0; `tryCatch` now means the Result helper in `try`.
|
|
46
|
+
|
|
47
|
+
4. **Node-only modules.** `crypto`, `security`, and `file` import `node:crypto` / `node:fs`; `logger` uses pino. Don't ship these to a browser bundle. `events` is the opposite — it wraps DOM `EventTarget` and is browser-only. `os`, `process`, `node`, and `system` probe for `process` / `window` and degrade rather than throw.
|
|
48
|
+
|
|
49
|
+
5. **`./types` is types-only.** It has a `types` field and no `import` field on purpose — use it for `import type { Prettify, Merge } from '@rtorcato/js-common/types'` only.
|
|
50
|
+
|
|
51
|
+
6. **Some helpers need a peer input you must supply.** `convertCurrency(amount, rate)` takes the rate — the library does no FX lookup. `checkEnv(schema)` needs a Zod object schema and throws with the list of missing keys.
|
|
52
|
+
|
|
53
|
+
## Module → exports
|
|
54
|
+
|
|
55
|
+
Import from `@rtorcato/js-common/<module>`.
|
|
56
|
+
|
|
57
|
+
| Module | Exports |
|
|
58
|
+
|---|---|
|
|
59
|
+
| abortController | createAbortController, abortPromise, withAbort, abortAfter |
|
|
60
|
+
| arrays | first, last, unique, flatten, chunk, compact, shuffle, groupBy |
|
|
61
|
+
| boolean | toBoolean, xor, and, or, not |
|
|
62
|
+
| colors | randomColor, matchingTextColor, hexToRgb, rgbToHex, isValidHex, darken, lighten |
|
|
63
|
+
| console | disableConsole, clearConsole |
|
|
64
|
+
| crypto | hashString, randomHex, hmacHash, base64Encode, base64Decode |
|
|
65
|
+
| currency | getCurrencySymbol, getCurrencyName, getCurrencyLocale, formatPrice, formatPriceCompact, parsePrice, parseCurrencyString, convertCurrency, isValidCurrencyCode, isValidCurrency |
|
|
66
|
+
| date | today, parseDate, formatDate, daysBetween, diffInHours, diffInMinutes, isLeapYear, addDays, subDays, addMonths, getDayOfWeek, startOfDay, endOfDay, isWeekend, isSameDay, isToday, formatRelative |
|
|
67
|
+
| datetime | nowIso, parseIsoDateTime, formatDateTimeLocal, getTimezoneOffset, toUtcDate, unixTimestamp, unixMillis, getIsoWeek, getIsoWeekInfo |
|
|
68
|
+
| emails | isValidEmail, normalizeEmail, maskEmail, getEmailDomain, isFreeEmailProvider |
|
|
69
|
+
| env | getENV, isDev, isProd, isTest, getNodeEnv, checkEnv, RootApiEnvSchema |
|
|
70
|
+
| errors | createCustomError, isErrorName, getErrorMessage, assert, tryWithFallback |
|
|
71
|
+
| events | on, emit, onceEvent, preventDefault, stopPropagation |
|
|
72
|
+
| fetch | fetchWithTimeout, postJson, getJson, fetchText, handleApiError |
|
|
73
|
+
| file | readFileAsString, writeFileAsString, fileExists, deleteFile, getFileExtension |
|
|
74
|
+
| functions | once, debounce, throttle, compose, pipe |
|
|
75
|
+
| geometry | distance2D, midpoint2D, angle2D, pointInRect, rectsOverlap, polygonArea |
|
|
76
|
+
| html | escapeHtml, unescapeHtml, stripHtmlTags, textToHtml, containsHtml |
|
|
77
|
+
| i18n | detectLanguage, formatNumber, formatDateI18n, t |
|
|
78
|
+
| interval | runInterval, clearIntervalById |
|
|
79
|
+
| json | safeJsonParse, safeJsonStringify, isValidJson, deepCloneJson |
|
|
80
|
+
| logger | logger (pino instance — pretty in dev, JSON in prod) |
|
|
81
|
+
| logging | logWithTimestamp, info, warn, error, captureConsole, ConsoleLevel |
|
|
82
|
+
| maps | invertMap, mapValues, mergeMaps, objectToMap, mapToObject |
|
|
83
|
+
| mime-types | lookup, types, extensions, mimeTypes |
|
|
84
|
+
| node | nodeVersionCheck, getNodeMajorVersion, isNode, requireOptional |
|
|
85
|
+
| numbers | clamp, roundTo, formatPercent, isFiniteNumber, isInteger, between, sum, average, mod, min, max |
|
|
86
|
+
| objects | isPlainObject, deepMerge, omit, pick, deepClone |
|
|
87
|
+
| os | getOsPlatform, getOsRelease, getOsArch, getHomeDir, getTmpDir |
|
|
88
|
+
| process | getProcessId, getProcessUptime, getCwd, getProcessPlatform, exitProcess, isCI |
|
|
89
|
+
| promises | delay, to, withTimeout, all, allSettled, race |
|
|
90
|
+
| random | randomInt, randomFloat, randomBool, randomElement, randomString |
|
|
91
|
+
| regex | escapeRegExp, testRegex, matchAll, replaceAllRegex, splitByRegex |
|
|
92
|
+
| security | stripScriptish, isStrongPassword, generateSecureToken |
|
|
93
|
+
| sets | union, intersection, difference, isSubset, isSuperset, setToArray, arrayToSet |
|
|
94
|
+
| sleep | sleep, sleepSync, sleepRandom, sleepWithAbort |
|
|
95
|
+
| strings | titleCase, capitalize, camelCase, kebabCase, snakeCase, truncate, padStart, padEnd, replaceString, reverse, slugify, words, wordCount, pluralize, ordinalize, isBlank, mask, template |
|
|
96
|
+
| system | isMacOs, isWindows, isLinux, isIOS, isAndroid, getPlatform, isTouchDevice |
|
|
97
|
+
| time | nowTime, nowTimeShort, parseTime, formatTime, secondsBetween, pad2 |
|
|
98
|
+
| try | tryCatch, isSuccess, Result, Success, Failure |
|
|
99
|
+
| types | Prettify, Merge (types only) |
|
|
100
|
+
| url | isValidUrl, getQueryParams, setQueryParam, removeQueryParam, joinUrl, getHostname |
|
|
101
|
+
| uuid | getUUID, getUUIDv7, getShortUUID, toShortUUID, fromShortUUID, isUUID, isUUIDv4, isNilUUID, getUUIDVersion, getNilUUID, uuidToBytes, bytesToUUID |
|
|
102
|
+
| validation | isDefined, isString, isNumber, isBoolean, isArray, isObject, isEmail, isUrl |
|
|
103
|
+
|
|
104
|
+
## CLI
|
|
105
|
+
|
|
106
|
+
The package also ships a binary for shell use:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npx @rtorcato/js-common@latest date today
|
|
110
|
+
npx @rtorcato/js-common@latest math sum 1 2 3
|
|
111
|
+
npx @rtorcato/js-common@latest text capitalize "hello world"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
See [CLI.md](https://github.com/rtorcato/js-common/blob/main/CLI.md) for the full command list.
|
|
115
|
+
|
|
116
|
+
For full signatures and examples, see <https://rtorcato.github.io/js-common/>.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
# Changelog — frozen at 2.8.2
|
|
2
|
+
|
|
3
|
+
**This file stops at 2.8.2 and will not be updated again. It is not the place to
|
|
4
|
+
look for what shipped.**
|
|
5
|
+
|
|
6
|
+
[**GitHub Releases**](https://github.com/rtorcato/js-common/releases) is the
|
|
7
|
+
canonical record, and the [changelog page on the docs
|
|
8
|
+
site](https://rtorcato.github.io/js-common/docs/changelog) is built from it.
|
|
9
|
+
|
|
10
|
+
Why: `@semantic-release/git` is dropped from this repo's plugin list because the
|
|
11
|
+
`code-scanning-main` ruleset rejects the release commit with `GH013` — a commit
|
|
12
|
+
created seconds earlier can never have CodeQL results (see
|
|
13
|
+
[#153](https://github.com/rtorcato/js-common/issues/153) and
|
|
14
|
+
[#211](https://github.com/rtorcato/js-common/issues/211)). Nothing commits this
|
|
15
|
+
file back to `main`, so it holds whatever the last release with that plugin
|
|
16
|
+
wrote. The same applies to the `version` field in `package.json`.
|
|
17
|
+
|
|
18
|
+
Kept in the repo rather than deleted because GitHub Releases only go back to
|
|
19
|
+
v1.2.0 — the hand-written `1.0.0` section at the bottom is the only record of
|
|
20
|
+
that release, which is also why this file carries two formats.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## [2.8.2](https://github.com/rtorcato/js-common/compare/v2.8.1...v2.8.2) (2026-07-23)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* **release:** upgrade npm for OIDC trusted publishing ([#110](https://github.com/rtorcato/js-common/issues/110)) ([93db8b5](https://github.com/rtorcato/js-common/commit/93db8b56041e916c63c1e250312e8527df931cc4))
|
|
30
|
+
|
|
1
31
|
## [2.8.1](https://github.com/rtorcato/js-common/compare/v2.8.0...v2.8.1) (2026-06-12)
|
|
2
32
|
|
|
3
33
|
|
package/CONTRIBUTORS.md
CHANGED
|
@@ -31,6 +31,11 @@ We welcome contributions from everyone! Here's how you can help:
|
|
|
31
31
|
8. Push to your branch (`git push origin feature/amazing-feature`)
|
|
32
32
|
9. Open a Pull Request
|
|
33
33
|
|
|
34
|
+
Adding a helper? Check [MODULE-BOUNDARIES.md](MODULE-BOUNDARIES.md) first. It
|
|
35
|
+
records which module owns what, and the rule that no name is exported from two
|
|
36
|
+
modules — module paths are frozen, so a helper in the wrong place is expensive
|
|
37
|
+
to move later.
|
|
38
|
+
|
|
34
39
|
### 📝 Documentation
|
|
35
40
|
- Improve README.md, code comments, or JSDoc
|
|
36
41
|
- Add examples for existing functions
|
package/README.md
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# js-common
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<picture>
|
|
5
|
+
<source media="(max-width: 600px)" srcset="./brand/banner-mobile.png">
|
|
6
|
+
<img src="./brand/banner.png" alt="js-common — Tree-shakeable TypeScript utilities: tiny bundles, full type safety, CLI included." width="100%">
|
|
7
|
+
</picture>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
[](https://github.com/rtorcato/js-common/actions/workflows/ci.yml)
|
|
5
11
|
[](https://badge.fury.io/js/%40rtorcato%2Fjs-common)
|
|
12
|
+
[](https://www.npmjs.com/package/@rtorcato/js-common)
|
|
13
|
+
[](https://bundlephobia.com/package/@rtorcato/js-common)
|
|
6
14
|
[](https://opensource.org/licenses/MIT)
|
|
7
15
|
[](https://www.typescriptlang.org/)
|
|
8
16
|
[](https://nodejs.org/)
|
|
@@ -18,7 +26,7 @@ A comprehensive set of common JavaScript and TypeScript utilities for Node.js pr
|
|
|
18
26
|
- **Tree-shakeable** — import only what you need via subpath exports
|
|
19
27
|
- **TypeScript** — full type definitions, JSDoc on every public API
|
|
20
28
|
- **CLI included** — optional binary for use in scripts and terminals
|
|
21
|
-
- **Modular** — one module per concern,
|
|
29
|
+
- **Modular** — one module per concern, 44 subpaths
|
|
22
30
|
- **Minimal runtime deps** — only `date-fns`, `date-fns-tz`, `luxon`, `pino`, `uuid`, `short-uuid`, `zod`. CLI packages (`chalk`, `commander`, `figlet`, …) are `optionalDependencies` and only needed for the CLI.
|
|
23
31
|
|
|
24
32
|
## Installation
|
|
@@ -27,11 +35,41 @@ A comprehensive set of common JavaScript and TypeScript utilities for Node.js pr
|
|
|
27
35
|
npm install @rtorcato/js-common
|
|
28
36
|
```
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
Pre-release builds are published to the `beta` dist-tag, so they never reach a plain `npm install`:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install @rtorcato/js-common@beta
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Use with AI
|
|
45
|
+
|
|
46
|
+
An agent skill lives in [`skills/js-common`](./skills/js-common/SKILL.md) — it teaches an AI coding agent the subpath-import rules, which same-named helper belongs to which module, the three error idioms, which modules are Node-only, and the full module → exports map.
|
|
47
|
+
|
|
48
|
+
**Claude Code** — this repo is its own plugin marketplace:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
/plugin marketplace add rtorcato/js-common
|
|
52
|
+
/plugin install js-common@js-common
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Cursor, Copilot, Codex and other tools** — read [`AGENTS.md`](./AGENTS.md), the cross-tool convention file. It carries the same guidance and also ships in the npm tarball, so tools that scan `node_modules` find it at `node_modules/@rtorcato/js-common/AGENTS.md`.
|
|
31
56
|
|
|
32
|
-
|
|
57
|
+
**Any tool the [`skills`](https://www.npmjs.com/package/skills) CLI supports:**
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx skills add https://github.com/rtorcato/js-common --skill js-common
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`AGENTS.md` is generated from `SKILL.md` by `pnpm sync:agents`; CI fails if they drift. Edit `SKILL.md`, never `AGENTS.md`.
|
|
64
|
+
|
|
65
|
+
## Migrating
|
|
66
|
+
|
|
67
|
+
**2.x → 3.x** — every helper now has exactly one home. `./formatting` and `./math` are gone, and where two modules shipped the same name the loser was deleted rather than aliased, so you get a build error naming the fix. One helper was also renamed rather than moved: `sanitizeString` is now `stripScriptish`, because the old name promised sanitising it never did — it removes `<script>` blocks and inline `on*` handlers and nothing else. The full before/after map is in the [migration guide](https://rtorcato.github.io/js-common/docs/guides/migration); the reasoning is in [MODULE-BOUNDARIES.md](MODULE-BOUNDARIES.md).
|
|
68
|
+
|
|
69
|
+
**1.x → 2.x** — the only breaking change in 2.0 is a rename in the `errors` module:
|
|
33
70
|
|
|
34
71
|
```ts
|
|
72
|
+
// boundary-check: ignore — quotes the pre-2.0 API on purpose
|
|
35
73
|
// 1.x — swallow errors and fall back to a default value
|
|
36
74
|
import { tryCatch } from '@rtorcato/js-common/errors'
|
|
37
75
|
const data = await tryCatch(() => fetchData(), [])
|
|
@@ -76,16 +114,16 @@ See [CLI.md](./CLI.md) for complete CLI documentation.
|
|
|
76
114
|
```typescript
|
|
77
115
|
// Import specific modules (recommended for tree-shaking)
|
|
78
116
|
import { formatDate, today, daysBetween } from '@rtorcato/js-common/date'
|
|
79
|
-
import {
|
|
80
|
-
import {
|
|
117
|
+
import { isValidEmail, normalizeEmail } from '@rtorcato/js-common/emails'
|
|
118
|
+
import { getUUID, isUUID } from '@rtorcato/js-common/uuid'
|
|
81
119
|
import { sum, average, roundTo } from '@rtorcato/js-common/numbers'
|
|
82
|
-
import { capitalize,
|
|
120
|
+
import { capitalize, titleCase } from '@rtorcato/js-common/strings'
|
|
83
121
|
|
|
84
122
|
// Example usage
|
|
85
123
|
console.log(today()) // "2026-05-29"
|
|
86
124
|
console.log(sum([1, 2, 3, 4, 5])) // 15
|
|
87
125
|
console.log(capitalize('hello world')) // "Hello world"
|
|
88
|
-
console.log(
|
|
126
|
+
console.log(getUUID()) // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
|
|
89
127
|
```
|
|
90
128
|
|
|
91
129
|
### Bundle Size Impact
|
|
@@ -94,6 +132,10 @@ Each module is shipped as its own subpath export so bundlers only include what y
|
|
|
94
132
|
|
|
95
133
|
## Available Modules
|
|
96
134
|
|
|
135
|
+
Which module a helper belongs to — and why no helper is exported from two of
|
|
136
|
+
them — is recorded in [MODULE-BOUNDARIES.md](MODULE-BOUNDARIES.md). These paths
|
|
137
|
+
are frozen as of that record.
|
|
138
|
+
|
|
97
139
|
### Date & Time
|
|
98
140
|
```typescript
|
|
99
141
|
import { today, formatDate, daysBetween, isLeapYear } from '@rtorcato/js-common/date'
|
|
@@ -102,29 +144,27 @@ import { nowTime, parseTime, secondsBetween } from '@rtorcato/js-common/time'
|
|
|
102
144
|
import { runInterval, clearIntervalById } from '@rtorcato/js-common/interval'
|
|
103
145
|
```
|
|
104
146
|
|
|
105
|
-
### Numbers
|
|
147
|
+
### Numbers
|
|
106
148
|
```typescript
|
|
107
|
-
import { sum, average, roundTo, clamp,
|
|
108
|
-
import { add, subtract, multiply, divide } from '@rtorcato/js-common/math'
|
|
149
|
+
import { sum, average, roundTo, clamp, formatPercent } from '@rtorcato/js-common/numbers'
|
|
109
150
|
import { randomInt, randomFloat, randomBool, randomElement } from '@rtorcato/js-common/random'
|
|
110
151
|
```
|
|
111
152
|
|
|
112
153
|
### Text & Strings
|
|
113
154
|
```typescript
|
|
114
|
-
import { capitalize,
|
|
115
|
-
import { slugify, truncate, removeEmojis } from '@rtorcato/js-common/strings'
|
|
155
|
+
import { slugify, truncate, capitalize, titleCase, pluralize } from '@rtorcato/js-common/strings'
|
|
116
156
|
import { escapeHtml, unescapeHtml, stripHtmlTags } from '@rtorcato/js-common/html'
|
|
117
157
|
import { escapeRegExp, matchAll, replaceAllRegex } from '@rtorcato/js-common/regex'
|
|
118
|
-
import { detectLanguage, formatNumber,
|
|
158
|
+
import { detectLanguage, formatNumber, formatDateI18n, t } from '@rtorcato/js-common/i18n'
|
|
119
159
|
```
|
|
120
160
|
|
|
121
161
|
### Security & Validation
|
|
122
162
|
```typescript
|
|
123
163
|
import { isStrongPassword, generateSecureToken } from '@rtorcato/js-common/security'
|
|
124
|
-
import { isValidEmail,
|
|
164
|
+
import { isValidEmail, maskEmail } from '@rtorcato/js-common/emails'
|
|
125
165
|
import { isValidUrl } from '@rtorcato/js-common/url'
|
|
126
|
-
import { isString, isNumber, isArray, isObject } from '@rtorcato/js-common/validation'
|
|
127
|
-
import { toBoolean,
|
|
166
|
+
import { isString, isNumber, isBoolean, isArray, isObject } from '@rtorcato/js-common/validation'
|
|
167
|
+
import { toBoolean, and, or, not, xor } from '@rtorcato/js-common/boolean'
|
|
128
168
|
```
|
|
129
169
|
|
|
130
170
|
### Data Structures
|
|
@@ -138,7 +178,7 @@ import { union, intersection, difference, isSubset } from '@rtorcato/js-common/s
|
|
|
138
178
|
|
|
139
179
|
### Async & Control Flow
|
|
140
180
|
```typescript
|
|
141
|
-
import { delay,
|
|
181
|
+
import { delay, withTimeout, allSettled } from '@rtorcato/js-common/promises'
|
|
142
182
|
import { debounce, throttle, once } from '@rtorcato/js-common/functions'
|
|
143
183
|
import { sleep } from '@rtorcato/js-common/sleep'
|
|
144
184
|
import { tryCatch } from '@rtorcato/js-common/try'
|
|
@@ -166,7 +206,7 @@ import { info, warn, error, captureConsole } from '@rtorcato/js-common/logging'
|
|
|
166
206
|
- `colors` — color manipulation and conversion
|
|
167
207
|
- `crypto` — cryptographic helpers
|
|
168
208
|
- `currency` — currency formatting and conversion
|
|
169
|
-
- `events` — event
|
|
209
|
+
- `events` — DOM event helpers (`on`, `emit`, `onceEvent`)
|
|
170
210
|
- `fetch` — HTTP request helpers
|
|
171
211
|
- `file` — file system helpers
|
|
172
212
|
- `geometry` — 2D geometry calculations
|
|
@@ -209,10 +249,10 @@ pnpm run benchmark
|
|
|
209
249
|
|
|
210
250
|
## Documentation site
|
|
211
251
|
|
|
212
|
-
The full documentation site lives in [`apps/
|
|
252
|
+
The full documentation site lives in [`apps/docs`](./apps/docs) and is built with [Docusaurus](https://docusaurus.io/). It auto-deploys to GitHub Pages on every push to `main` that touches `apps/docs/**`.
|
|
213
253
|
|
|
214
254
|
```bash
|
|
215
|
-
# Run the docs locally (http://localhost:
|
|
255
|
+
# Run the docs locally (http://localhost:3000/js-common/)
|
|
216
256
|
pnpm --filter @rtorcato/js-common-docs dev
|
|
217
257
|
|
|
218
258
|
# Build the static site
|
|
@@ -221,6 +261,10 @@ pnpm --filter @rtorcato/js-common-docs build
|
|
|
221
261
|
|
|
222
262
|
Live site: <https://rtorcato.github.io/js-common/>
|
|
223
263
|
|
|
264
|
+
## Roadmap
|
|
265
|
+
|
|
266
|
+
Direction and progress are tracked entirely on GitHub — see the [milestones](https://github.com/rtorcato/js-common/milestones) for the stages (shipped 2.x modules, the beta npm preview, the v1.0 stable API) and the [open issues](https://github.com/rtorcato/js-common/issues) for day-to-day work.
|
|
267
|
+
|
|
224
268
|
## Contributing
|
|
225
269
|
|
|
226
270
|
Contributions are welcome! Please read [CONTRIBUTORS.md](./CONTRIBUTORS.md) for guidelines.
|
|
@@ -231,6 +275,11 @@ Contributions are welcome! Please read [CONTRIBUTORS.md](./CONTRIBUTORS.md) for
|
|
|
231
275
|
4. Run the test suite: `pnpm test`
|
|
232
276
|
5. Submit a pull request
|
|
233
277
|
|
|
278
|
+
## Related packages
|
|
279
|
+
|
|
280
|
+
- [@rtorcato/browser-common](https://github.com/rtorcato/browser-common) — Browser Web API wrappers (clipboard, observers, storage, etc.)
|
|
281
|
+
- [@rtorcato/repo-tooling](https://github.com/rtorcato/repo-tooling) — Project scaffolding for TypeScript libraries (Biome, Vitest, Husky, semantic-release)
|
|
282
|
+
|
|
234
283
|
## License
|
|
235
284
|
|
|
236
285
|
MIT © [Richard Torcato](https://github.com/rtorcato)
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Creates a new AbortController and returns its controller and signal.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* const { controller, signal } = createAbortController()
|
|
7
|
+
* signal.aborted // false
|
|
8
|
+
* controller.abort()
|
|
9
|
+
* signal.aborted // true
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
3
12
|
* @returns {{ controller: AbortController, signal: AbortSignal }}
|
|
4
13
|
*/
|
|
5
14
|
export declare function createAbortController(): {
|
|
@@ -8,12 +17,33 @@ export declare function createAbortController(): {
|
|
|
8
17
|
};
|
|
9
18
|
/**
|
|
10
19
|
* Returns a promise that rejects when the given AbortSignal is aborted.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const { controller, signal } = createAbortController()
|
|
24
|
+
* const pending = abortPromise(signal)
|
|
25
|
+
* controller.abort()
|
|
26
|
+
* await pending.catch((err) => err.name) // 'AbortError'
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
11
29
|
* @param signal The AbortSignal to listen to.
|
|
12
30
|
* @returns {Promise<never>}
|
|
13
31
|
*/
|
|
14
32
|
export declare function abortPromise(signal: AbortSignal): Promise<never>;
|
|
15
33
|
/**
|
|
16
34
|
* Wraps a promise and rejects it if the signal is aborted.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const { controller, signal } = createAbortController()
|
|
39
|
+
* const slow = new Promise<string>((resolve) => setTimeout(() => resolve('done'), 50))
|
|
40
|
+
*
|
|
41
|
+
* await withAbort(slow, signal) // 'done'
|
|
42
|
+
*
|
|
43
|
+
* controller.abort()
|
|
44
|
+
* await withAbort(slow, signal).catch((err) => err.name) // 'AbortError'
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
17
47
|
* @param promise The promise to wrap.
|
|
18
48
|
* @param signal The AbortSignal.
|
|
19
49
|
* @returns {Promise<T>}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/abortController/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/abortController/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB;;;EAGpC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAchE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAEjF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAEjG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrays.test-d.d.ts","sourceRoot":"","sources":["../../src/arrays/arrays.test-d.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as n,b as a,c as t,e as u,h as s}from"../chunks/chunk-5IA77ERW.js";import"../chunks/chunk-ANN5UYCF.js";import{describe as o,expectTypeOf as e,it as r}from"vitest";o("arrays \u2014 types",()=>{r("first/last preserve element type and add undefined",()=>{e(n([1,2,3])).toEqualTypeOf(),e(n(["a","b"])).toEqualTypeOf(),e(a([{id:1}])).toEqualTypeOf()}),r("unique preserves element type",()=>{e(t([1,2,3])).toEqualTypeOf(),e(t(["a"])).toEqualTypeOf()}),r("chunk returns array of arrays of the element type",()=>{e(u([1,2,3],2)).toEqualTypeOf(),e(u(["a","b"],1)).toEqualTypeOf()}),r("groupBy preserves element type in the grouped arrays",()=>{let i=s([{kind:"a",n:1}],p=>p.kind);e(i).toEqualTypeOf()})});
|
package/dist/arrays/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../chunks/chunk-
|
|
1
|
+
import{a,b,c,d,e,f,g,h}from"../chunks/chunk-5IA77ERW.js";import"../chunks/chunk-ANN5UYCF.js";export{e as chunk,f as compact,a as first,d as flatten,h as groupBy,b as last,g as shuffle,c as unique};
|
package/dist/boolean/index.d.ts
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Converts a value to a boolean.
|
|
3
3
|
* Accepts 'true', '1', 1 as true; 'false', '0', 0 as false.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* toBoolean('true') // true
|
|
8
|
+
* toBoolean('0') // false
|
|
9
|
+
* toBoolean(1) // true
|
|
10
|
+
* toBoolean(2) // false
|
|
11
|
+
* toBoolean(null) // false
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
4
14
|
* @param value The value to convert.
|
|
5
15
|
* @returns The boolean representation.
|
|
6
16
|
*/
|
|
7
17
|
export declare function toBoolean(value: unknown): boolean;
|
|
8
|
-
/**
|
|
9
|
-
* Checks if a value is a boolean.
|
|
10
|
-
* @param value The value to check.
|
|
11
|
-
* @returns True if the value is a boolean, false otherwise.
|
|
12
|
-
*/
|
|
13
|
-
export declare function isBoolean(value: unknown): value is boolean;
|
|
14
18
|
/**
|
|
15
19
|
* Returns the logical exclusive OR (XOR) of two booleans.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* xor(true, false) // true
|
|
24
|
+
* xor(true, true) // false
|
|
25
|
+
* xor(false, false) // false
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
16
28
|
* @param a First boolean.
|
|
17
29
|
* @param b Second boolean.
|
|
18
30
|
* @returns True if exactly one of a or b is true.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/boolean/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/boolean/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWjD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAElD;AAED;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEvC"}
|
package/dist/boolean/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../chunks/chunk-ANN5UYCF.js";function e(o){if(typeof o=="boolean")return o;if(typeof o=="string"){let n=o.trim().toLowerCase();if(n==="true"||n==="1")return!0;if(n==="false"||n==="0")return!1}return typeof o=="number"?o===1:!!o}function r(o
|
|
1
|
+
import"../chunks/chunk-ANN5UYCF.js";function e(o){if(typeof o=="boolean")return o;if(typeof o=="string"){let n=o.trim().toLowerCase();if(n==="true"||n==="1")return!0;if(n==="false"||n==="0")return!1}return typeof o=="number"?o===1:!!o}function r(o,n){return!!(o?!n:n)}function t(o,n){return o&&n}function f(o,n){return o||n}function a(o){return!o}export{t as and,a as not,f as or,e as toBoolean,r as xor};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function u(n){return n[0]}function T(n){return n.length?n[n.length-1]:void 0}function f(n){return Array.from(new Set(n))}function i(n){return n.flat()}function l(n,e){if(e<1)throw new Error("Chunk size must be at least 1");let t=[];for(let r=0;r<n.length;r+=e)t.push(n.slice(r,r+e));return t}function s(n){return n.filter(Boolean)}function c(n){let e=n.slice();for(let t=e.length-1;t>0;t--){let r=Math.floor(Math.random()*(t+1));[e[t],e[r]]=[e[r],e[t]]}return e}function h(n,e){return n.reduce((t,r)=>{let o=e(r);return t[o]||(t[o]=[]),t[o].push(r),t},{})}export{u as a,T as b,f as c,i as d,l as e,s as f,c as g,h};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function i(e){return new Promise(r=>setTimeout(r,e))}async function u(e){try{return[null,await e]}catch(r){return[r,void 0]}}function s(e,r,t=new Error("Timeout")){return Promise.race([e,new Promise((n,o)=>setTimeout(()=>o(t),r))])}function m(e){return Promise.all(e)}function T(e){return Promise.allSettled(e)}function P(e){return Promise.race(e)}export{i as a,u as b,s as c,m as d,T as e,P as f};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function r(n){return Object.prototype.toString.call(n)==="[object Object]"}function s(n,o){let t={...n};for(let e in o)r(o[e])&&r(t[e])?t[e]=s(t[e],o[e]):t[e]=o[e];return t}function c(n,o){let t={...n};for(let e of o)delete t[e];return t}function i(n,o){let t={};for(let e of o)e in n&&(t[e]=n[e]);return t}function T(n){return structuredClone(n)}export{r as a,s as b,c,i as d,T as e};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as e}from"./chunk-FBDKWWIQ.js";import{createRequire as t}from"node:module";import r from"pino";function o(){try{return t(import.meta.url).resolve("pino-pretty"),!0}catch{return!1}}var s=e()&&o()?r({level:"debug",transport:{target:"pino-pretty",options:{colorize:!0,ignore:"pid,hostname,time",levelFirst:!1,singleLine:!0,customColors:"err:red,info:blue",translateTime:"HH:MM:ss"}}}):r({level:"info"});export{s as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function o(n){let t=!1,e;return function(...r){return t||(t=!0,e=n.apply(this,r)),e}}function i(n,t){let e;return function(...r){clearTimeout(e),e=setTimeout(()=>n.apply(this,r),t)}}function u(n,t){let e=0;return function(...r){let a=Date.now();a-e>=t&&(e=a,n.apply(this,r))}}function T(...n){return t=>n.reduceRight((e,r)=>r(e),t)}function s(...n){return t=>n.reduce((e,r)=>r(e),t)}export{o as a,i as b,u as c,T as d,s as e};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// Catalog of the functions the CLI advertises, used by `list`, `interactive`
|
|
2
|
+
// and `add`.
|
|
3
|
+
//
|
|
4
|
+
// Three names per entry, and they are deliberately different things:
|
|
5
|
+
// - `name` the CLI verb (`js-common math avg`) — part of the CLI surface
|
|
6
|
+
// - `exportName` the real library export (`average`) — what `add` must print
|
|
7
|
+
// - `subpath` the published module the export lives in (`numbers`)
|
|
8
|
+
//
|
|
9
|
+
// `subpath` is per entry, not per category: the CLI groups by task ('math',
|
|
10
|
+
// 'system') while the library groups by module — 'math' spans `numbers` and
|
|
11
|
+
// `random`, 'system' spans `process` and `node`.
|
|
12
|
+
//
|
|
13
|
+
// `src/cli/catalog.test.ts` asserts both halves, so this cannot drift back into
|
|
14
|
+
// fiction: every `exportName` really is exported by `src/<subpath>/index.ts`,
|
|
15
|
+
// and every `name` really is a command registered in `src/cli/cli.ts`. The
|
|
16
|
+
// second check exists because it wasn't there — `file`, `security`, `validate`,
|
|
17
|
+
// `text pad` and `system ci` were advertised here for long enough that `list`
|
|
18
|
+
// printed commands that errored when run.
|
|
19
|
+
export const functionCategories = {
|
|
20
|
+
date: {
|
|
21
|
+
name: '📅 Date & Time',
|
|
22
|
+
functions: [
|
|
23
|
+
{
|
|
24
|
+
name: 'today',
|
|
25
|
+
description: "Get today's date (YYYY-MM-DD)",
|
|
26
|
+
exportName: 'today',
|
|
27
|
+
subpath: 'date',
|
|
28
|
+
example: `const date = today() // '${new Date().toISOString().slice(0, 10)}'`,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'now',
|
|
32
|
+
description: 'Get current timestamp',
|
|
33
|
+
exportName: 'nowIso',
|
|
34
|
+
subpath: 'datetime',
|
|
35
|
+
example: `const timestamp = nowIso() // '${new Date().toISOString()}'`,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'between',
|
|
39
|
+
description: 'Calculate days between dates',
|
|
40
|
+
exportName: 'daysBetween',
|
|
41
|
+
subpath: 'date',
|
|
42
|
+
example: `const days = daysBetween('2023-01-01', '2023-12-31') // 364`,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
math: {
|
|
47
|
+
name: '🔢 Mathematical',
|
|
48
|
+
functions: [
|
|
49
|
+
{
|
|
50
|
+
name: 'sum',
|
|
51
|
+
description: 'Calculate sum of numbers',
|
|
52
|
+
exportName: 'sum',
|
|
53
|
+
subpath: 'numbers',
|
|
54
|
+
example: `const total = sum([1, 2, 3, 4, 5]) // 15`,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'avg',
|
|
58
|
+
description: 'Calculate average of numbers',
|
|
59
|
+
exportName: 'average',
|
|
60
|
+
subpath: 'numbers',
|
|
61
|
+
example: `const mean = average([10, 20, 30]) // 20`,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'random',
|
|
65
|
+
description: 'Generate random number',
|
|
66
|
+
exportName: 'randomInt',
|
|
67
|
+
subpath: 'random',
|
|
68
|
+
example: `const num = randomInt(1, 100) // 42`,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'round',
|
|
72
|
+
description: 'Round to decimal places',
|
|
73
|
+
exportName: 'roundTo',
|
|
74
|
+
subpath: 'numbers',
|
|
75
|
+
example: `const rounded = roundTo(3.14159, 2) // 3.14`,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'clamp',
|
|
79
|
+
description: 'Clamp between min/max',
|
|
80
|
+
exportName: 'clamp',
|
|
81
|
+
subpath: 'numbers',
|
|
82
|
+
example: `const clamped = clamp(150, 0, 100) // 100`,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
text: {
|
|
87
|
+
name: '📝 Text Formatting',
|
|
88
|
+
functions: [
|
|
89
|
+
{
|
|
90
|
+
name: 'capitalize',
|
|
91
|
+
description: 'Capitalize first letter',
|
|
92
|
+
exportName: 'capitalize',
|
|
93
|
+
subpath: 'strings',
|
|
94
|
+
example: `const text = capitalize('hello world') // 'Hello world'`,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'title',
|
|
98
|
+
description: 'Convert to title case',
|
|
99
|
+
exportName: 'titleCase',
|
|
100
|
+
subpath: 'strings',
|
|
101
|
+
example: `const heading = titleCase('hello world') // 'Hello World'`,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
system: {
|
|
106
|
+
name: '💻 System Info',
|
|
107
|
+
functions: [
|
|
108
|
+
{
|
|
109
|
+
name: 'pid',
|
|
110
|
+
description: 'Get process ID',
|
|
111
|
+
exportName: 'getProcessId',
|
|
112
|
+
subpath: 'process',
|
|
113
|
+
example: `const processId = getProcessId() // 12345`,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'uptime',
|
|
117
|
+
description: 'Get process uptime',
|
|
118
|
+
exportName: 'getProcessUptime',
|
|
119
|
+
subpath: 'process',
|
|
120
|
+
example: `const uptime = getProcessUptime() // 123.45`,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'node-version',
|
|
124
|
+
description: 'Get Node.js version',
|
|
125
|
+
exportName: 'getNodeMajorVersion',
|
|
126
|
+
subpath: 'node',
|
|
127
|
+
example: `const major = getNodeMajorVersion() // 22`,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
};
|