@ix-xs/node-comfort 1.1.31 → 2.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/CHANGELOG.md +190 -0
- package/LICENSE +21 -0
- package/README.md +210 -748
- package/index.js +84 -13
- package/package.json +201 -21
- package/src/Arr.js +901 -0
- package/src/Async.js +585 -0
- package/src/Cache.js +329 -0
- package/src/Checker.js +979 -188
- package/src/Cli.js +1034 -0
- package/src/Color.js +415 -0
- package/src/Crypto.js +707 -0
- package/src/Emitter.js +289 -0
- package/src/Env.js +555 -0
- package/src/FS.js +1483 -768
- package/src/Func.js +692 -0
- package/src/Http.js +538 -0
- package/src/Id.js +418 -0
- package/src/Logger.js +739 -307
- package/src/Num.js +849 -0
- package/src/Obj.js +904 -0
- package/src/SQLite.js +1308 -994
- package/src/Schema.js +1586 -0
- package/src/Str.js +999 -0
- package/src/Sys.js +511 -0
- package/src/Time.js +1323 -0
- package/src/Utils.js +321 -325
- package/src/errors.js +292 -0
- package/types/index.d.ts +693 -120
- package/types/src/Arr.d.ts +562 -0
- package/types/src/Arr.d.ts.map +1 -0
- package/types/src/Async.d.ts +321 -0
- package/types/src/Async.d.ts.map +1 -0
- package/types/src/Cache.d.ts +195 -0
- package/types/src/Cache.d.ts.map +1 -0
- package/types/src/Checker.d.ts +609 -81
- package/types/src/Checker.d.ts.map +1 -1
- package/types/src/Cli.d.ts +582 -0
- package/types/src/Cli.d.ts.map +1 -0
- package/types/src/Color.d.ts +294 -0
- package/types/src/Color.d.ts.map +1 -0
- package/types/src/Crypto.d.ts +534 -0
- package/types/src/Crypto.d.ts.map +1 -0
- package/types/src/Emitter.d.ts +170 -0
- package/types/src/Emitter.d.ts.map +1 -0
- package/types/src/Env.d.ts +382 -0
- package/types/src/Env.d.ts.map +1 -0
- package/types/src/FS.d.ts +709 -201
- package/types/src/FS.d.ts.map +1 -1
- package/types/src/Func.d.ts +455 -0
- package/types/src/Func.d.ts.map +1 -0
- package/types/src/Http.d.ts +374 -0
- package/types/src/Http.d.ts.map +1 -0
- package/types/src/Id.d.ts +200 -0
- package/types/src/Id.d.ts.map +1 -0
- package/types/src/Logger.d.ts +374 -24
- package/types/src/Logger.d.ts.map +1 -1
- package/types/src/Num.d.ts +578 -0
- package/types/src/Num.d.ts.map +1 -0
- package/types/src/Obj.d.ts +475 -0
- package/types/src/Obj.d.ts.map +1 -0
- package/types/src/SQLite.d.ts +647 -305
- package/types/src/SQLite.d.ts.map +1 -1
- package/types/src/Schema.d.ts +940 -0
- package/types/src/Schema.d.ts.map +1 -0
- package/types/src/Str.d.ts +696 -0
- package/types/src/Str.d.ts.map +1 -0
- package/types/src/Sys.d.ts +269 -0
- package/types/src/Sys.d.ts.map +1 -0
- package/types/src/Time.d.ts +664 -0
- package/types/src/Time.d.ts.map +1 -0
- package/types/src/Utils.d.ts +154 -102
- package/types/src/Utils.d.ts.map +1 -1
- package/types/src/errors.d.ts +292 -0
- package/types/src/errors.d.ts.map +1 -0
- package/tsconfig.json +0 -18
- package/types/index.d.ts.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [2.0.0] - 2026-09-12
|
|
8
|
+
|
|
9
|
+
node-comfort becomes a complete, zero-dependency standard library for Node.js: 23 namespaces and classes,
|
|
10
|
+
more than 500 documented and typed functions, and an editor experience checked on every commit.
|
|
11
|
+
|
|
12
|
+
### Security
|
|
13
|
+
|
|
14
|
+
- **Prototype pollution fixed** in `obj.set()` and `obj.unflatten()` (1.2.0). A path such as
|
|
15
|
+
`"__proto__.isAdmin"` coming from user input could modify `Object.prototype`. Every object helper
|
|
16
|
+
(`set`, `unset`, `merge`, `mergeWith`, `defaults`, `unflatten`, `clone`, `fromEntries`...) now ignores
|
|
17
|
+
`__proto__`, `constructor` and `prototype` keys. **Upgrade if you pass user-controlled paths or objects
|
|
18
|
+
to these functions.**
|
|
19
|
+
- The 1.x filesystem helpers searched the whole folder tree for a file with the same name when a relative
|
|
20
|
+
path did not exist, which could read, overwrite or delete the wrong file. This implicit search is gone
|
|
21
|
+
(see `fs` below).
|
|
22
|
+
- `id.code()` no longer has a modulo bias (rejection sampling).
|
|
23
|
+
|
|
24
|
+
### Breaking changes
|
|
25
|
+
|
|
26
|
+
Each item explains what to change. Most projects only need the SQLite and Node.js items.
|
|
27
|
+
|
|
28
|
+
1. **Node.js 22.13 or newer is required** (`engines`). Node 20 reaches end of life, and 1.x already
|
|
29
|
+
required `node:sqlite`, which is only available without a flag since Node 22.13.
|
|
30
|
+
2. **Deep imports are no longer allowed**: the package defines an `exports` map. Replace
|
|
31
|
+
`require("@ix-xs/node-comfort/src/Logger")` by `require("@ix-xs/node-comfort").logger`, or by the
|
|
32
|
+
official entry point of the namespace: `require("@ix-xs/node-comfort/logger")`.
|
|
33
|
+
3. **SQLite methods throw instead of returning `{ error }`.** Failures throw a `nc.errors.SQLiteError`
|
|
34
|
+
(with `sql` and `sqliteCode`, for example `"SQLITE_CONSTRAINT_UNIQUE"`). Success values are unchanged.
|
|
35
|
+
```js
|
|
36
|
+
// 1.x
|
|
37
|
+
const result = await db.insert("users", data);
|
|
38
|
+
if (result.error) console.error(result.error);
|
|
39
|
+
// 2.0
|
|
40
|
+
try {
|
|
41
|
+
db.insert("users", data);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (error.sqliteCode === "SQLITE_CONSTRAINT_UNIQUE") console.error("Email already used");
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
`db.transaction()` re-throws the error after rolling back (it used to return `{ error }`).
|
|
47
|
+
4. **SQLite methods are synchronous.** They return values directly, like the underlying engine. `await`
|
|
48
|
+
keeps working, but `.then()` chains on their results must be removed. `db.transaction()` still accepts
|
|
49
|
+
async callbacks (it then returns a promise).
|
|
50
|
+
5. **`db.getAll()` no longer limits to 50 rows and no longer sorts by default.** Pass `{ limit: 50 }` to keep
|
|
51
|
+
a limit, and `{ orderBy: "id", direction: "DESC" }` to keep the old order. When `orderBy` is given without
|
|
52
|
+
`direction`, the order is now ascending (it was descending).
|
|
53
|
+
6. **SQLite tables are read from the database file.** 1.x only knew the tables created with `createTable()`
|
|
54
|
+
in the same process (`get()` returned `undefined` and `getAll()` returned `[]` for the others). Tables are
|
|
55
|
+
now found through `sqlite_master`, and an unknown table throws a `SQLiteError`.
|
|
56
|
+
7. **SQLite `BOOLEAN` and `JSON` columns are converted.** Reading a `BOOLEAN` column returns `true`/`false`
|
|
57
|
+
(it returned `1`/`0`) and a `JSON` column returns the parsed value. Writing booleans, objects, arrays and
|
|
58
|
+
dates now works (1.x threw "cannot be bound"). Disable with `new nc.SQLite(path, { booleans: false, json: false })`.
|
|
59
|
+
8. **`warn`, `error` and `fatal` logs are written to stderr**, like `console.warn` and `console.error`.
|
|
60
|
+
Colors are disabled when the output is not a terminal (files, pipes, CI logs) and with `NO_COLOR`;
|
|
61
|
+
use `FORCE_COLOR=1` to force them.
|
|
62
|
+
9. **Logger markup: `overline` draws a real overline.** It used to strike the text through; use
|
|
63
|
+
`strikethrough` for that.
|
|
64
|
+
10. **`func.timeout()` rejects with a `nc.errors.TimeoutError`.** It is still an `Error` with the same
|
|
65
|
+
message; only `error.name` (`"TimeoutError"`) and `error.code` (`"ETIMEDOUT"`) are new.
|
|
66
|
+
11. **`num.round()` rounds negative halves away from zero** (`-2.5` gives `-3`, it gave `-2`), consistently
|
|
67
|
+
with positive numbers, and never returns `-0`. Decimal precision is fixed: `round(1.005, 2)` is `1.01`.
|
|
68
|
+
12. **`str.length()`, `str.reverse()`, `str.truncate()` and `str.center()` count graphemes**, not UTF-16
|
|
69
|
+
code units: `str.length("👨👩👧")` is `1`, and emoji or accents are never cut in half.
|
|
70
|
+
13. **The filesystem helpers no longer search the folder tree** when a relative path does not exist
|
|
71
|
+
(see Security). Use the new `nc.find("config.json")` to search explicitly.
|
|
72
|
+
14. **`dontCrash()` only removes the listeners it added.** 1.x removed every `uncaughtException`, `exit`
|
|
73
|
+
and signal listener of the process, including those of other libraries. Calling it again replaces the
|
|
74
|
+
previous handlers, and the returned controller has `dispose()`.
|
|
75
|
+
15. **Stricter or more complete validators**: `isEmail()` accepts international addresses but rejects
|
|
76
|
+
consecutive or trailing dots; `isUUID()` accepts versions 1 to 8 and the nil/max UUIDs (use
|
|
77
|
+
`{ version }` to restrict); `isURL()` accepts an options object (`protocols`, `requireTld`).
|
|
78
|
+
16. **`JSONString()` converts `Map` to objects and `Set` to arrays** (they gave `{}`), and an object used
|
|
79
|
+
twice is serialized twice instead of being replaced by `"[Circular]"` (only real cycles are).
|
|
80
|
+
|
|
81
|
+
### Deprecated
|
|
82
|
+
|
|
83
|
+
- `id.hash()`, `id.hmac()` and `id.safeEqual()` moved to `nc.crypto` (same signatures). The aliases keep
|
|
84
|
+
working and will be removed in 3.0.0.
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
|
|
88
|
+
**Packaging and editor experience**
|
|
89
|
+
- Lazy loading: `require("@ix-xs/node-comfort")` takes about 3 ms, and each namespace is loaded the first
|
|
90
|
+
time it is used. A script that only logs never loads the database, the HTTP client or the crypto code.
|
|
91
|
+
- An entry point per namespace (`@ix-xs/node-comfort/str`, `/http`, `/sqlite`...), which keeps ES module
|
|
92
|
+
imports light and makes bundling easier.
|
|
93
|
+
- A documentation website at https://ix-xs.github.io/node-comfort/: guides for every namespace, the full
|
|
94
|
+
API reference, recipes, and search.
|
|
95
|
+
- Complete TypeScript declarations generated from the JSDoc: hover documentation with examples for every
|
|
96
|
+
function, parameter and option, completion after `nc.` and `nodeComfort.`, auto-import of `nc`,
|
|
97
|
+
`nodeComfort` and every flat helper, type guards, typed dot paths, schema inference, generic caches,
|
|
98
|
+
typed events, SQLite columns suggested in `where` filters.
|
|
99
|
+
- ES module named imports (`import { str, isEmail, nc } from "@ix-xs/node-comfort"`) and
|
|
100
|
+
`const { nc } = require(...)`.
|
|
101
|
+
- `docs/API.md`, a complete API reference generated from the types.
|
|
102
|
+
- Tests (`node --test`) and CI on Linux, macOS and Windows with Node 22, 24 and the latest release;
|
|
103
|
+
editor checks with TypeScript 5.9, 6 and 7.
|
|
104
|
+
|
|
105
|
+
**New namespaces and classes**
|
|
106
|
+
- `nc.crypto`: `hashPassword`/`verifyPassword`/`needsRehash` (scrypt), `encrypt`/`decrypt` (AES-256-GCM),
|
|
107
|
+
`signJWT`/`verifyJWT`/`decodeJWT` (HS256/384/512), `totp`/`verifyTOTP`/`totpSecret`/`totpURI` (2FA),
|
|
108
|
+
`hash`, `hmac`, `safeEqual`, `generateKey`, `randomBytes`, `randomInt`, `toBase64`, `fromBase64`.
|
|
109
|
+
- `nc.color`: chainable terminal colors (`color.red.bold("x")`), hex/RGB/256 colors, automatic level
|
|
110
|
+
detection and downgrade, `strip`, `width`, `link`, `gradient`, `create`.
|
|
111
|
+
- `nc.cli`: typed `args` with generated `--help`, `prompt`, `password`, `confirm`, `select`,
|
|
112
|
+
`multiselect`, `spinner`, `progress`, `table`, `box`, `isInteractive`, `size`, `clear`.
|
|
113
|
+
- `nc.sys`: `run` (no shell, Windows-safe arguments), `exec`, `which`, `open`, `onShutdown` (graceful
|
|
114
|
+
shutdown), `isWindows`, `isMac`, `isLinux`, `isCI`, `isDocker`, `isWSL`, `info`, `memory`.
|
|
115
|
+
- `nc.async`: `map`/`forEach`/`filter` with a concurrency limit, `series`, `limit`, `queue` (priorities,
|
|
116
|
+
timeouts), `mutex`, `deferred`, `settle`, `props`, `poll`, `sleep`.
|
|
117
|
+
- `nc.schema`: schema validation with TypeScript inference (`string`, `number`, `boolean`, `bigint`, `date`,
|
|
118
|
+
`literal`, `enum`, `array`, `object`, `union`, `tuple`, `record`, `lazy`, `instanceOf`, `custom`, `coerce`,
|
|
119
|
+
`refine`, `transform`, `default`, `catch`...).
|
|
120
|
+
- `nc.http`: HTTP client on top of `fetch` with JSON, query objects, auth, timeouts, retries with
|
|
121
|
+
`Retry-After`, hooks, clients (`create`/`extend`), downloads with progress.
|
|
122
|
+
- `nc.env`: `.env` parser and loader, typed getters (`number`, `bool`, `port`, `url`, `duration`, `list`,
|
|
123
|
+
`json`, `oneOf`) and `validate()` reporting every invalid variable at once. `NODE_COMFORT_DOTENV=false`
|
|
124
|
+
disables the automatic `.env` loading.
|
|
125
|
+
- `nc.errors`: `NodeComfortError`, `AssertionError`, `TimeoutError`, `AbortError`, `ValidationError`,
|
|
126
|
+
`HttpError`, `JWTError`, `ProcessError`, `SQLiteError`, each with a stable `code`.
|
|
127
|
+
- `nc.Cache`: LRU cache with TTL, `getOrSet` (concurrent loads shared), `wrap`, `prune`, `stats`.
|
|
128
|
+
- `nc.Emitter`: typed event emitter with `once`, `onAny`, `emitAsync`, `waitFor`, `iterate`.
|
|
129
|
+
|
|
130
|
+
**Existing modules**
|
|
131
|
+
- Logger: `trace`, `fatal` and `silent` levels, `LOG_LEVEL`, `LOG_FORMAT=json`, structured fields,
|
|
132
|
+
`createLogger` with scope, file output with rotation, `child` (its `fields` are added to the parent's,
|
|
133
|
+
for per-request loggers), `table`, `box`, `divider`, markup colors in
|
|
134
|
+
hex and RGB, `setLevel`, `configure`; every function returns the logger for chaining.
|
|
135
|
+
- FS: `glob` (relative patterns, or absolute ones that search where they point), `find`, `readLines`,
|
|
136
|
+
`writeFile` (atomic), `ensureFolder`, `ensureFile`, `touch`, `remove`,
|
|
137
|
+
`copy`, `move`, `isFile`, `isFolder`, `folderSize`, `tempFolder`, `sanitizeFilename`, chunked
|
|
138
|
+
`hashFile`, `readJSON` with comments, atomic `writeJSON`, debounced `watch`.
|
|
139
|
+
- Checker: about 30 new guards (`isIP`, `isPort`, `isSemver`, `isJWT`, `isHexColor`, `isBase64`,
|
|
140
|
+
`isCreditCard`, `isArrayOf`, `isOneOf`, `isClass`, `isBlank`...), `assert` and `assertType`.
|
|
141
|
+
- `str`, `num`, `arr`, `obj`, `func`, `time`, `id`: more than 120 new functions, among them `str.dedent`,
|
|
142
|
+
`str.wrap`, `str.plural`, `str.closest`, `str.mask`, `num.currency`, `num.percentile`, `num.parseBytes`,
|
|
143
|
+
`arr.paginate`, `arr.windows`, `arr.cartesian`, `obj.diff`, `obj.mergeWith`, `func.pipe`,
|
|
144
|
+
`time.setLocale`/`time.setTimezone` (every date function in any language and time zone),
|
|
145
|
+
`time.calendar`, `time.cron`, `time.every`, `time.nextRun`, `id.uuidv7`, `id.snowflake`.
|
|
146
|
+
- `num.setLocale()` sets the default language of `format`, `currency`, `percent`, `abbreviate`,
|
|
147
|
+
`ordinal` and `formatBytes`, like `time.setLocale()` does for dates.
|
|
148
|
+
- SQLite: rich `where` operators (`gt`, `in`, `like`, `between`, `$or`...), `insertMany`, `exists`,
|
|
149
|
+
`tables`, `columns`, `hasTable`, `table()` handles, `migrate()` (versioned with `user_version`),
|
|
150
|
+
`backup()`, `vacuum()`, `iterate()`, `fn()` (SQL functions in JavaScript), nested transactions with
|
|
151
|
+
savepoints, prepared statement cache, `readOnly`/`busyTimeout` options, `using` support.
|
|
152
|
+
|
|
153
|
+
### Fixed
|
|
154
|
+
|
|
155
|
+
- `const { merge } = nc.obj` (and any destructured helper) threw because functions relied on `this`.
|
|
156
|
+
- `titleCase()` broke words with accented letters.
|
|
157
|
+
- Logger groups were not indented consistently, and logging a circular object crashed.
|
|
158
|
+
- `unescapeHTML()` now decodes numeric entities (`'`, `'`) and ` `.
|
|
159
|
+
- `memoize()` no longer keeps rejected promises: a failed call is retried next time.
|
|
160
|
+
- `watch()` follows the real path of what it watches, so a short (8.3) or symlinked path no longer
|
|
161
|
+
crashes the watcher on Windows.
|
|
162
|
+
- Dates, maps, sets and plain objects coming from a worker or a `vm` context are recognized by
|
|
163
|
+
`obj`, `schema`, `time`, `checker.isPlainObject` and `JSONString` (1.x compared prototypes, which
|
|
164
|
+
are not shared between realms).
|
|
165
|
+
|
|
166
|
+
### Migration checklist
|
|
167
|
+
|
|
168
|
+
1. Upgrade Node.js to 22.13+.
|
|
169
|
+
2. Replace deep imports by the namespaces (`nc.logger`, `nc.fs`...).
|
|
170
|
+
3. SQLite: replace `if (result.error)` checks by `try/catch`, add `{ limit, orderBy, direction: "DESC" }`
|
|
171
|
+
where you relied on the old `getAll()` defaults, and check code that compared `BOOLEAN` columns to `1`/`0`.
|
|
172
|
+
4. If you parse your application's output, remember that warnings and errors now go to stderr.
|
|
173
|
+
5. Replace `nc.id.hash/hmac/safeEqual` by `nc.crypto.hash/hmac/safeEqual` (optional until 3.0).
|
|
174
|
+
|
|
175
|
+
## [1.2.0]
|
|
176
|
+
|
|
177
|
+
### Added
|
|
178
|
+
|
|
179
|
+
- Namespaces `str`, `num`, `arr`, `obj`, `func`, `time` and `id`.
|
|
180
|
+
- Checker: 22 new guards (`isEmail`, `isURL`, `isUUID`, `isEmpty`, `isPlainObject`...).
|
|
181
|
+
- Logger: `info`, `success`, `warn`, `error` and `debug` levels.
|
|
182
|
+
- FS: `readJSON`, `writeJSON`, `appendFile`, `exists`, `stat`, `fileSize`, `hashFile`, `emptyFolder`.
|
|
183
|
+
- SQLite: `:memory:` databases.
|
|
184
|
+
|
|
185
|
+
### Fixed
|
|
186
|
+
|
|
187
|
+
- SQLite: the folder of the database was created in one place and the file opened in another.
|
|
188
|
+
|
|
189
|
+
[2.0.0]: https://github.com/ix-xs/node-comfort/compare/v1.2.0...v2.0.0
|
|
190
|
+
[1.2.0]: https://github.com/ix-xs/node-comfort/releases/tag/v1.2.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ix-xs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|