@dbx-tools/shared-core 0.6.60 → 0.6.62
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/README.md +73 -10
- package/index.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/src/env.js +4 -6
- package/lib/src/object.d.ts +208 -7
- package/lib/src/object.js +277 -37
- package/lib/src/string.js +1 -4
- package/package.json +1 -1
- package/src/env.ts +3 -4
- package/src/object.ts +360 -29
- package/src/string.ts +0 -4
package/README.md
CHANGED
|
@@ -206,9 +206,41 @@ const isRunnable = predicate
|
|
|
206
206
|
short-circuits. `predicate.create()` returns composable predicates with `and`,
|
|
207
207
|
`or`, and `negate`, used heavily by the projen engine.
|
|
208
208
|
|
|
209
|
-
##
|
|
209
|
+
## Serializable Values And Stable Identities
|
|
210
210
|
|
|
211
211
|
```ts
|
|
212
|
+
if (object.isSerializableValue(requestBody)) {
|
|
213
|
+
await bus.broadcast("orders", { type: "order.updated", body: requestBody });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const key = object.toStableKey({ schema: "billing", version: 2 });
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
`object.isSerializableValue()` answers "does this survive a JSON round trip
|
|
220
|
+
unchanged", which is stricter than `JSON.stringify` not throwing: that succeeds
|
|
221
|
+
while turning a `Date` into a string, `NaN` into `null`, and a `Map` into `{}`,
|
|
222
|
+
and while dropping `undefined`. It narrows to `SerializableValue` instead of
|
|
223
|
+
throwing, so it doubles as the validator for a request body. Type a serializing
|
|
224
|
+
boundary as `SerializableValue` to catch the same mistakes at compile time.
|
|
225
|
+
|
|
226
|
+
`object.toStableKey()` canonicalizes a value so an identity can be derived from
|
|
227
|
+
it. Object key order does not affect the result, but types and structure do:
|
|
228
|
+
`1` and `"1"` differ, and so do `["a", "bc"]` and `["ab", "c"]`. It throws on a
|
|
229
|
+
cycle, a non-finite number, or a function/symbol rather than returning an
|
|
230
|
+
identity two callers could disagree about. `@dbx-tools/postgres` derives both its
|
|
231
|
+
advisory-lock ids and its notification channel names through it. Use
|
|
232
|
+
`hash.fnvHash()` instead when a short collision-tolerant digest is enough — its
|
|
233
|
+
canonicalizer is looser and folds every `Date` onto one token.
|
|
234
|
+
|
|
235
|
+
## Numbers, Dates, And Durations
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
object.toNumber("1,000"); // 1000
|
|
239
|
+
object.toNumber(" -2.5 "); // -2.5
|
|
240
|
+
object.toNumber("12.5 %"); // 0.125
|
|
241
|
+
object.toNumber(""); // undefined - `Number("")` would be 0
|
|
242
|
+
object.toNumber("12px"); // undefined
|
|
243
|
+
|
|
212
244
|
object.toDate("2026-08-02"); // a date or ISO instant
|
|
213
245
|
object.toDate("1785697899"); // epoch SECONDS (not the year 1785697899)
|
|
214
246
|
object.toDate(1785697899000); // epoch millis
|
|
@@ -219,14 +251,24 @@ object.toDate("nope"); // undefined - never throws
|
|
|
219
251
|
object.toDuration("1 hour 30 minutes"); // 5_400_000
|
|
220
252
|
object.toDuration("2ms"); // 2
|
|
221
253
|
object.toDuration("-7d"); // -604_800_000
|
|
254
|
+
object.toDuration("2026-08-02"); // ms from now until that instant
|
|
222
255
|
```
|
|
223
256
|
|
|
224
|
-
|
|
225
|
-
they are deliberately lenient: whitespace between amount and unit is
|
|
226
|
-
units are case-insensitive, and plurals and abbreviations are
|
|
227
|
-
=== `2 milliseconds`, `1h` === `1 hr` === `1 Hour`). Signs make
|
|
228
|
-
OFFSET, which is what lets `toDate` read `-30d` / `12 hours ago` /
|
|
229
|
-
instants.
|
|
257
|
+
All three are for values typed by HAND into env vars, CLI flags, and config
|
|
258
|
+
files, so they are deliberately lenient: whitespace between amount and unit is
|
|
259
|
+
optional, units are case-insensitive, and plurals and abbreviations are
|
|
260
|
+
equivalent (`2ms` === `2 milliseconds`, `1h` === `1 hr` === `1 Hour`). Signs make
|
|
261
|
+
a duration an OFFSET, which is what lets `toDate` read `-30d` / `12 hours ago` /
|
|
262
|
+
`in 45s` as instants.
|
|
263
|
+
|
|
264
|
+
`toNumber` is the base the other two are built on, and the reason to reach for it
|
|
265
|
+
over `Number(value)` is that `Number` invents values: `""`, `null`, `[]`, and a
|
|
266
|
+
whitespace string all become `0`, so every caller has to re-check the result.
|
|
267
|
+
`toNumber` returns `undefined` instead, and accepts the spellings a person
|
|
268
|
+
actually types — digit-group separators, a bare fraction, a trailing point, an
|
|
269
|
+
exponent, a trailing percent. `ToNumberOptions` disables the `separators` and
|
|
270
|
+
`percent` leniencies for a string whose other characters carry meaning; a SQL
|
|
271
|
+
cell uses that so `"1,000"` in a text column stays the string the query returned.
|
|
230
272
|
|
|
231
273
|
`toDate` exists rather than `new Date(value)` because a bare epoch usually
|
|
232
274
|
arrives as a STRING (`date +%s`, a JSON field, a copied log line) and
|
|
@@ -238,6 +280,26 @@ than `1`. Neither function throws - like `toBoolean` they return `undefined`, so
|
|
|
238
280
|
the caller decides whether a bad value is fatal, a warning, or a fallback
|
|
239
281
|
(`@dbx-tools/tunnel`'s `TUNNEL_AUTH_SESSION_CUTOFF` warns and carries on).
|
|
240
282
|
|
|
283
|
+
### Dates And Durations Are Inverses
|
|
284
|
+
|
|
285
|
+
Each function falls back to the other, so one field accepts both readings: a
|
|
286
|
+
duration reaching `toDate` resolves against now, and a date reaching
|
|
287
|
+
`toDuration` becomes the signed offset from now (`date - now`, so a past instant
|
|
288
|
+
is negative). Each tries its own reading first — `toDate` runs `Date.parse`
|
|
289
|
+
before the duration fallback — and recurses with the other's parser off, so a
|
|
290
|
+
value cannot bounce between them.
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
object.toDate("30 days ago", { parseDuration: false }); // undefined
|
|
294
|
+
object.toDuration("2026-08-02", { parseDate: false }); // undefined
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Turn the fallback off where only one reading can be correct. A stored timestamp
|
|
298
|
+
or an `expires_at` field must not accept a duration, because resolving against
|
|
299
|
+
the current clock makes the same input mean something different on every call. A
|
|
300
|
+
timeout or a poll interval must not accept a date, because it would yield a
|
|
301
|
+
plausible but wrong number that also drifts.
|
|
302
|
+
|
|
241
303
|
## Iterables
|
|
242
304
|
|
|
243
305
|
```ts
|
|
@@ -369,9 +431,10 @@ without paying formatting cost when disabled.
|
|
|
369
431
|
- `json` - non-throwing `parse()` and record-narrowing `parseRecord()`.
|
|
370
432
|
- `string` - tokenization, slugs, identifiers, human labels, string coercion,
|
|
371
433
|
config lists, descriptions, pluralization, and HTML escaping.
|
|
372
|
-
- `object` - record checks, boolean/date/duration coercion, present-only
|
|
373
|
-
spreading, deep equality,
|
|
374
|
-
|
|
434
|
+
- `object` - record checks, number/boolean/date/duration coercion, present-only
|
|
435
|
+
field spreading, deep equality, JSON-round-trip guards
|
|
436
|
+
(`isSerializableValue`), canonical identity keys (`toStableKey`), shape types,
|
|
437
|
+
and lazy sequence transforms + collection helpers.
|
|
375
438
|
- `env` - config-over-environment resolution: strings, booleans, positive
|
|
376
439
|
numbers/integers, and lists, with env-name fallback chains. `name()` gives the
|
|
377
440
|
primary variable name for a log line or error - an `EnvKey` may be a bare
|
package/index.ts
CHANGED
|
@@ -28,7 +28,7 @@ export type { MemoizeOptions } from "./src/function.ts";
|
|
|
28
28
|
export type { HeaderLike } from "./src/http.ts";
|
|
29
29
|
export type { LogLevel, Logger } from "./src/log.ts";
|
|
30
30
|
export type { UrlLike, IpVersion, ParsedIp, Cidr, UrlBuilder, ParseEmailsOptions } from "./src/net.ts";
|
|
31
|
-
export type { Sequence, Container, Collection, OneOrMany, NameLike, NonFunctionKeys, DeepEqualComparator } from "./src/object.ts";
|
|
31
|
+
export type { Sequence, Container, Collection, OneOrMany, NameLike, NonFunctionKeys, SerializablePrimitive, SerializableValue, ToNumberOptions, ToDateOptions, ToDurationOptions, DeepEqualComparator } from "./src/object.ts";
|
|
32
32
|
export type { PatternOptions } from "./src/pattern.ts";
|
|
33
33
|
export type { PredicateFunction, TypePredicateFunction, PredicateInput, Predicate } from "./src/predicate.ts";
|
|
34
34
|
export type { TokenizeOptions, KeyOptions, IdentifierOptions, Description } from "./src/string.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export type { MemoizeOptions } from "./src/function.ts";
|
|
|
24
24
|
export type { HeaderLike } from "./src/http.ts";
|
|
25
25
|
export type { LogLevel, Logger } from "./src/log.ts";
|
|
26
26
|
export type { UrlLike, IpVersion, ParsedIp, Cidr, UrlBuilder, ParseEmailsOptions } from "./src/net.ts";
|
|
27
|
-
export type { Sequence, Container, Collection, OneOrMany, NameLike, NonFunctionKeys, DeepEqualComparator } from "./src/object.ts";
|
|
27
|
+
export type { Sequence, Container, Collection, OneOrMany, NameLike, NonFunctionKeys, SerializablePrimitive, SerializableValue, ToNumberOptions, ToDateOptions, ToDurationOptions, DeepEqualComparator } from "./src/object.ts";
|
|
28
28
|
export type { PatternOptions } from "./src/pattern.ts";
|
|
29
29
|
export type { PredicateFunction, TypePredicateFunction, PredicateInput, Predicate } from "./src/predicate.ts";
|
|
30
30
|
export type { TokenizeOptions, KeyOptions, IdentifierOptions, Description } from "./src/string.ts";
|
package/lib/index.js
CHANGED
|
@@ -19,4 +19,4 @@ export * as string from "./src/string.js";
|
|
|
19
19
|
export * as token from "./src/token.js";
|
|
20
20
|
export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand.js";
|
|
21
21
|
export { ACCESS_TOKEN_HEADER, USER_ID_HEADER, USER_EMAIL_HEADER } from "./src/token.js";
|
|
22
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxLQUFLLEtBQUssTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxjQUFjLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBRXhDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBYXpKLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCAqIGFzIGFzeW5jIGZyb20gXCIuL3NyYy9hc3luYy50c1wiO1xuZXhwb3J0ICogYXMgYnJhbmQgZnJvbSBcIi4vc3JjL2JyYW5kLnRzXCI7XG5leHBvcnQgKiBhcyBlbnYgZnJvbSBcIi4vc3JjL2Vudi50c1wiO1xuZXhwb3J0ICogYXMgZXJyb3IgZnJvbSBcIi4vc3JjL2Vycm9yLnRzXCI7XG5leHBvcnQgKiBhcyBleGVjdXRpb24gZnJvbSBcIi4vc3JjL2V4ZWN1dGlvbi50c1wiO1xuZXhwb3J0ICogYXMgZnVuY3Rpb25Nb2R1bGUgZnJvbSBcIi4vc3JjL2Z1bmN0aW9uLnRzXCI7XG5leHBvcnQgKiBhcyBoYXNoIGZyb20gXCIuL3NyYy9oYXNoLnRzXCI7XG5leHBvcnQgKiBhcyBodHRwIGZyb20gXCIuL3NyYy9odHRwLnRzXCI7XG5leHBvcnQgKiBhcyBqc29uIGZyb20gXCIuL3NyYy9qc29uLnRzXCI7XG5leHBvcnQgKiBhcyBsb2cgZnJvbSBcIi4vc3JjL2xvZy50c1wiO1xuZXhwb3J0ICogYXMgbmV0IGZyb20gXCIuL3NyYy9uZXQudHNcIjtcbmV4cG9ydCAqIGFzIG9iamVjdCBmcm9tIFwiLi9zcmMvb2JqZWN0LnRzXCI7XG5leHBvcnQgKiBhcyBwYXR0ZXJuIGZyb20gXCIuL3NyYy9wYXR0ZXJuLnRzXCI7XG5leHBvcnQgKiBhcyBwcmVkaWNhdGUgZnJvbSBcIi4vc3JjL3ByZWRpY2F0ZS50c1wiO1xuZXhwb3J0ICogYXMgc3RyaW5nIGZyb20gXCIuL3NyYy9zdHJpbmcudHNcIjtcbmV4cG9ydCAqIGFzIHRva2VuIGZyb20gXCIuL3NyYy90b2tlbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBQb2xsQ29udGV4dCwgUG9sbFByb2R1Y2VyLCBQb2xsT3B0aW9ucyB9IGZyb20gXCIuL3NyYy9hc3luYy50c1wiO1xuZXhwb3J0IHsgREVGQVVMVF9CUkFORF9BU1NFVFMsIEJyYW5kQXNzZXRTZXRTY2hlbWEsIEJyYW5kQ29sb3JzU2NoZW1hLCBCcmFuZFZvaWNlU2NoZW1hLCBCcmFuZENvbnRleHRTY2hlbWEsIGRlZmF1bHRCcmFuZENvbnRleHQgfSBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCB0eXBlIHsgQnJhbmRDb250ZXh0LCBCcmFuZENvbnRleHRJbnB1dCwgQnJhbmRBc3NldFNldCB9IGZyb20gXCIuL3NyYy9icmFuZC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbnZLZXkgfSBmcm9tIFwiLi9zcmMvZW52LnRzXCI7XG5leHBvcnQgdHlwZSB7IEVycm9yQ29udGV4dCB9IGZyb20gXCIuL3NyYy9lcnJvci50c1wiO1xuZXhwb3J0IHR5cGUgeyBFeGVjdXRpb25SZXN1bHQsIEV4ZWN1dG9yLCBFeGVjdXRpb25GYWlsdXJlLCBSdW5PcHRpb25zIH0gZnJvbSBcIi4vc3JjL2V4ZWN1dGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBNZW1vaXplT3B0aW9ucyB9IGZyb20gXCIuL3NyYy9mdW5jdGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBIZWFkZXJMaWtlIH0gZnJvbSBcIi4vc3JjL2h0dHAudHNcIjtcbmV4cG9ydCB0eXBlIHsgTG9nTGV2ZWwsIExvZ2dlciB9IGZyb20gXCIuL3NyYy9sb2cudHNcIjtcbmV4cG9ydCB0eXBlIHsgVXJsTGlrZSwgSXBWZXJzaW9uLCBQYXJzZWRJcCwgQ2lkciwgVXJsQnVpbGRlciwgUGFyc2VFbWFpbHNPcHRpb25zIH0gZnJvbSBcIi4vc3JjL25ldC50c1wiO1xuZXhwb3J0IHR5cGUgeyBTZXF1ZW5jZSwgQ29udGFpbmVyLCBDb2xsZWN0aW9uLCBPbmVPck1hbnksIE5hbWVMaWtlLCBOb25GdW5jdGlvbktleXMsIFNlcmlhbGl6YWJsZVByaW1pdGl2ZSwgU2VyaWFsaXphYmxlVmFsdWUsIFRvTnVtYmVyT3B0aW9ucywgVG9EYXRlT3B0aW9ucywgVG9EdXJhdGlvbk9wdGlvbnMsIERlZXBFcXVhbENvbXBhcmF0b3IgfSBmcm9tIFwiLi9zcmMvb2JqZWN0LnRzXCI7XG5leHBvcnQgdHlwZSB7IFBhdHRlcm5PcHRpb25zIH0gZnJvbSBcIi4vc3JjL3BhdHRlcm4udHNcIjtcbmV4cG9ydCB0eXBlIHsgUHJlZGljYXRlRnVuY3Rpb24sIFR5cGVQcmVkaWNhdGVGdW5jdGlvbiwgUHJlZGljYXRlSW5wdXQsIFByZWRpY2F0ZSB9IGZyb20gXCIuL3NyYy9wcmVkaWNhdGUudHNcIjtcbmV4cG9ydCB0eXBlIHsgVG9rZW5pemVPcHRpb25zLCBLZXlPcHRpb25zLCBJZGVudGlmaWVyT3B0aW9ucywgRGVzY3JpcHRpb24gfSBmcm9tIFwiLi9zcmMvc3RyaW5nLnRzXCI7XG5leHBvcnQgeyBBQ0NFU1NfVE9LRU5fSEVBREVSLCBVU0VSX0lEX0hFQURFUiwgVVNFUl9FTUFJTF9IRUFERVIgfSBmcm9tIFwiLi9zcmMvdG9rZW4udHNcIjtcbiJdfQ==
|
package/lib/src/env.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @module
|
|
16
16
|
*/
|
|
17
|
-
import { toBoolean } from "./object.js";
|
|
17
|
+
import { toBoolean, toNumber } from "./object.js";
|
|
18
18
|
import { parseList, trimToNull } from "./string.js";
|
|
19
19
|
/** The ambient environment, or `{}` off-process (a browser). */
|
|
20
20
|
function environment() {
|
|
@@ -104,10 +104,8 @@ export function positiveInt(configured, keys, fallback) {
|
|
|
104
104
|
return toPositiveInt(configured) ?? toPositiveInt(text(keys)) ?? fallback;
|
|
105
105
|
}
|
|
106
106
|
function toPositiveNumber(value) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const parsed = Number(value);
|
|
110
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
107
|
+
const parsed = toNumber(value);
|
|
108
|
+
return parsed !== undefined && parsed > 0 ? parsed : undefined;
|
|
111
109
|
}
|
|
112
110
|
function toPositiveInt(value) {
|
|
113
111
|
const parsed = toPositiveNumber(value);
|
|
@@ -125,4 +123,4 @@ export function list(configured, keys, transform) {
|
|
|
125
123
|
const fromConfig = parseList(configured, transform);
|
|
126
124
|
return fromConfig.length > 0 ? fromConfig : parseList(text(keys), transform);
|
|
127
125
|
}
|
|
128
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW52LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Vudi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBVXBELGdFQUFnRTtBQUNoRSxTQUFTLFdBQVc7SUFDbEIsT0FBUSxVQUF3QyxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO0FBQ3RFLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FBQyxJQUFZO0lBQy9CLE9BQU8sT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxJQUFJLENBQUMsSUFBWTtJQUMvQixNQUFNLEdBQUcsR0FBRyxXQUFXLEVBQUUsQ0FBQztJQUMxQixLQUFLLE1BQU0sR0FBRyxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDM0QsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ25DLElBQUksS0FBSyxLQUFLLElBQUk7WUFBRSxPQUFPLEtBQUssQ0FBQztJQUNuQyxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLE1BQU0sQ0FBQyxVQUFtQixFQUFFLElBQVk7SUFDdEQsT0FBTyxVQUFVLENBQUMsVUFBVSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzlDLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxPQUFPLENBQUMsVUFBbUIsRUFBRSxJQUFZO0lBQ3ZELE9BQU8sU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsVUFBbUIsRUFBRSxJQUFZLEVBQUUsUUFBZ0I7SUFDaEYsT0FBTyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxRQUFRLENBQUM7QUFDbEYsQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxVQUFtQixFQUFFLElBQVksRUFBRSxRQUFnQjtJQUM3RSxPQUFPLGFBQWEsQ0FBQyxVQUFVLENBQUMsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDO0FBQzVFLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLEtBQWM7SUFDdEMsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLEVBQUU7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUM1RSxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0IsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3BFLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxLQUFjO0lBQ25DLE1BQU0sTUFBTSxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLE9BQU8sTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FDbEIsVUFBeUQsRUFDekQsSUFBWSxFQUNaLFNBQXFDO0lBRXJDLE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDcEQsT0FBTyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQy9FLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJlYWRpbmcgY29uZmlndXJhdGlvbiBvdXQgb2YgdGhlIGVudmlyb25tZW50LlxuICpcbiAqIEV2ZXJ5IHBsdWdpbiBjb25maWcgaW4gdGhpcyByZXBvIHJlc29sdmVzIHRoZSBzYW1lIHdheTogdGFrZSB0aGUgdHlwZWRcbiAqIGNvbmZpZyB2YWx1ZSB3aGVuIHRoZSBjYWxsZXIgc2V0IG9uZSwgZWxzZSBmYWxsIGJhY2sgdG8gb25lIG9yIG1vcmVcbiAqIGVudmlyb25tZW50IHZhcmlhYmxlcywgZWxzZSBhIGRlZmF1bHQuIFdyaXR0ZW4gYnkgaGFuZCB0aGF0IGJlY29tZXMgYVxuICogYGNvbmZpZy54ID8/IE51bWJlcihwcm9jZXNzLmVudi5YKWAgY2hhaW4gcGVyIGZpZWxkLCBhbmQgZWFjaCBwYWNrYWdlIGdyZXdcbiAqIGl0cyBvd24gYGZyb21FbnZgIC8gYHJlc29sdmVQb3NpdGl2ZUludGAgaGVscGVyIHdpdGggc2xpZ2h0bHkgZGlmZmVyZW50XG4gKiBjb2VyY2lvbiBydWxlcy4gVGhlc2UgYXJlIHRob3NlIGhlbHBlcnMsIG9uY2UuXG4gKlxuICogQnJvd3Nlci1zYWZlOiBgcHJvY2Vzc2AgaXMgcmVhY2hlZCB0aHJvdWdoIGBnbG9iYWxUaGlzYCBhbmQgZ3VhcmRlZCwgc28gdGhpc1xuICogbW9kdWxlIG5lZWRzIG5vIE5vZGUgdHlwZXMgYW5kIGlzIGluZXJ0IGluIGEgYnJvd3NlciAoZXZlcnkgbG9va3VwIG1pc3NlcyBhbmRcbiAqIHRoZSBjYWxsZXIncyBmYWxsYmFjayBhcHBsaWVzKS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgdG9Cb29sZWFuIH0gZnJvbSBcIi4vb2JqZWN0LnRzXCI7XG5pbXBvcnQgeyBwYXJzZUxpc3QsIHRyaW1Ub051bGwgfSBmcm9tIFwiLi9zdHJpbmcudHNcIjtcblxuLyoqIGBwcm9jZXNzYC1zaGFwZWQgdmlldyBvZmYgYGdsb2JhbFRoaXNgLCBzbyBubyBub2RlIHR5cGVzIGFyZSBuZWVkZWQuICovXG5pbnRlcmZhY2UgUHJvY2Vzc0xpa2Uge1xuICBlbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xufVxuXG4vKiogT25lIGVudiB2YXIgbmFtZSwgb3Igc2V2ZXJhbCB0cmllZCBpbiBvcmRlci4gKi9cbmV4cG9ydCB0eXBlIEVudktleSA9IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4vKiogVGhlIGFtYmllbnQgZW52aXJvbm1lbnQsIG9yIGB7fWAgb2ZmLXByb2Nlc3MgKGEgYnJvd3NlcikuICovXG5mdW5jdGlvbiBlbnZpcm9ubWVudCgpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgcmV0dXJuIChnbG9iYWxUaGlzIGFzIHsgcHJvY2Vzcz86IFByb2Nlc3NMaWtlIH0pLnByb2Nlc3M/LmVudiA/PyB7fTtcbn1cblxuLyoqXG4gKiBUaGUgUFJJTUFSWSAoY3VycmVudCwgbm9uLWRlcHJlY2F0ZWQpIG5hbWUgaW4gYW4ge0BsaW5rIEVudktleX0uXG4gKlxuICogVXNlIHRoaXMgd2hlbiBuYW1pbmcgYSB2YXJpYWJsZSBpbiBhIGxvZyBsaW5lIG9yIGVycm9yIHJhdGhlciB0aGFuIGluZGV4aW5nXG4gKiBga2V5c1swXWA6IGFuIHtAbGluayBFbnZLZXl9IG1heSBiZSBhIGJhcmUgc3RyaW5nLCBhbmQgYFwiVFVOTkVMX1hcIlswXWAgaXMgdGhlXG4gKiBjaGFyYWN0ZXIgYFwiVFwiYCwgd2hpY2ggcHJvZHVjZXMgYSBtZXNzYWdlIG5hbWluZyBhIHZhcmlhYmxlIHRoYXQgZG9lcyBub3RcbiAqIGV4aXN0LiBSZXR1cm5zIGBcIlwiYCBvbmx5IGZvciBhbiBlbXB0eSBsaXN0LCB3aGljaCBubyBjYWxsZXIgc2hvdWxkIGhhdmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGxvZ2dlci53YXJuKGAke2Vudi5uYW1lKEpXVF9TRUNSRVRfRU5WKX0gaXMgbm90IHNldGApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gbmFtZShrZXlzOiBFbnZLZXkpOiBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIGtleXMgPT09IFwic3RyaW5nXCIgPyBrZXlzIDogKGtleXNbMF0gPz8gXCJcIik7XG59XG5cbi8qKlxuICogRmlyc3Qgbm9uLWVtcHR5IHZhbHVlIGFtb25nIGBrZXlzYCwgdHJpbW1lZCwgZWxzZSBgbnVsbGAuXG4gKlxuICogU2V2ZXJhbCBuYW1lcyBmb3Igb25lIHNldHRpbmcgaXMgdGhlIG5vcm0gKGEgcGFja2FnZS1zcGVjaWZpYyB2YXJpYWJsZSBwbHVzXG4gKiB0aGUgRGF0YWJyaWNrcy1zdGFuZGFyZCBvbmUpLCBzbyBga2V5c2AgaXMgb3JkZXItc2Vuc2l0aXZlOiBlYXJsaWVyIG5hbWVzIHdpbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogZW52LnRleHQoW1wiVEVBTVNfQVBQX0lEXCIsIFwiTUlDUk9TT0ZUX0FQUF9JRFwiXSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0KGtleXM6IEVudktleSk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBlbnYgPSBlbnZpcm9ubWVudCgpO1xuICBmb3IgKGNvbnN0IGtleSBvZiB0eXBlb2Yga2V5cyA9PT0gXCJzdHJpbmdcIiA/IFtrZXlzXSA6IGtleXMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRyaW1Ub051bGwoZW52W2tleV0pO1xuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBzdHJpbmcgc2V0dGluZzogYGNvbmZpZ3VyZWRgIHdoZW4gc2V0IGFuZCBub24tZW1wdHksIGVsc2UgdGhlIGZpcnN0XG4gKiBub24tZW1wdHkgdmFyaWFibGUgYW1vbmcgYGtleXNgLCBlbHNlIGBudWxsYC5cbiAqXG4gKiBAZXhhbXBsZVxuICogZW52LnN0cmluZyhjb25maWcuaG9zdCwgXCJTTVRQX0hPU1RcIik7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmcoY29uZmlndXJlZDogdW5rbm93biwga2V5czogRW52S2V5KTogc3RyaW5nIHwgbnVsbCB7XG4gIHJldHVybiB0cmltVG9OdWxsKGNvbmZpZ3VyZWQpID8/IHRleHQoa2V5cyk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGJvb2xlYW4gc2V0dGluZyB0aHJvdWdoIHtAbGluayB0b0Jvb2xlYW59LCBzbyB0aGUgbG9vc2Ugc3BlbGxpbmdzIGFuXG4gKiBlbnYgdmFyIGFjdHVhbGx5IGNhcnJpZXMgKGAxYCwgYG9uYCwgYHllc2AsIC4uLikgYXJlIGFjY2VwdGVkLiBSZXR1cm5zXG4gKiBgdW5kZWZpbmVkYCB3aGVuIG5laXRoZXIgc291cmNlIGlzIGludGVycHJldGFibGUsIGxldHRpbmcgdGhlIGNhbGxlciBwaWNrIGFcbiAqIGRlZmF1bHQgd2l0aCBgPz9gLlxuICpcbiAqIEBleGFtcGxlXG4gKiBlbnYuYm9vbGVhbihjb25maWcuZnV6enksIFwiV0VCX1NFQVJDSF9GVVpaWVwiKSA/PyB0cnVlO1xuICovXG5leHBvcnQgZnVuY3Rpb24gYm9vbGVhbihjb25maWd1cmVkOiB1bmtub3duLCBrZXlzOiBFbnZLZXkpOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHRvQm9vbGVhbihjb25maWd1cmVkKSA/PyB0b0Jvb2xlYW4odGV4dChrZXlzKSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHBvc2l0aXZlLW51bWJlciBzZXR0aW5nIHRoYXQgbWF5IGJlIGZyYWN0aW9uYWwgKGEgc2NvcmUgdGhyZXNob2xkLFxuICogYSByYXRpbyk6IGBjb25maWd1cmVkYCB3aGVuIGl0IGlzIGEgZmluaXRlIG51bWJlciBncmVhdGVyIHRoYW4gemVybywgZWxzZSB0aGVcbiAqIGZpcnN0IHZhcmlhYmxlIGFtb25nIGBrZXlzYCB0aGF0IHBhcnNlcyB0aGF0IHdheSwgZWxzZSBgZmFsbGJhY2tgLlxuICpcbiAqIHtAbGluayBwb3NpdGl2ZUludH0gaXMgdGhlIHJpZ2h0IGNob2ljZSBmb3IgYSBjb3VudDsgdGhpcyBvbmUga2VlcHMgdGhlXG4gKiBmcmFjdGlvbiwgc28gYSBgMC40YCB0aHJlc2hvbGQgZG9lcyBub3QgZmxvb3IgdG8gYDBgLlxuICpcbiAqIEBleGFtcGxlXG4gKiBlbnYucG9zaXRpdmVOdW1iZXIoY29uZmlnLmZ1enp5VGhyZXNob2xkLCBcIlNFQVJDSF9GVVpaWV9USFJFU0hPTERcIiwgMC40KTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvc2l0aXZlTnVtYmVyKGNvbmZpZ3VyZWQ6IHVua25vd24sIGtleXM6IEVudktleSwgZmFsbGJhY2s6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiB0b1Bvc2l0aXZlTnVtYmVyKGNvbmZpZ3VyZWQpID8/IHRvUG9zaXRpdmVOdW1iZXIodGV4dChrZXlzKSkgPz8gZmFsbGJhY2s7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHBvc2l0aXZlLWludGVnZXIgc2V0dGluZyAoYSBwb3J0LCB0aW1lb3V0LCBwYWdlIHNpemUsIG9yIGNhcCk6XG4gKiBgY29uZmlndXJlZGAgd2hlbiBpdCBpcyBhIGZpbml0ZSBudW1iZXIgZ3JlYXRlciB0aGFuIHplcm8sIGVsc2UgdGhlIGZpcnN0XG4gKiB2YXJpYWJsZSBhbW9uZyBga2V5c2AgdGhhdCBwYXJzZXMgdGhhdCB3YXksIGVsc2UgYGZhbGxiYWNrYC4gRmxvb3JlZCwgc28gYVxuICogZnJhY3Rpb25hbCB2YWx1ZSBjYW4ndCBsZWFrIGludG8gYSBjb3VudC5cbiAqXG4gKiBBIG5vbi1udW1lcmljIG9yIG5vbi1wb3NpdGl2ZSB2YWx1ZSBpcyB0cmVhdGVkIGFzIGFic2VudCByYXRoZXIgdGhhbiBmYXRhbCAtXG4gKiB0aGVzZSBhcmUgY2VpbGluZ3MgYW5kIHRpbWVvdXRzIHdoZXJlIGEgc2FuZSBkZWZhdWx0IGJlYXRzIGEgYm9vdCBmYWlsdXJlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBlbnYucG9zaXRpdmVJbnQoY29uZmlnLnRpbWVvdXRNcywgXCJTRUFSQ0hfVElNRU9VVF9NU1wiLCAzMF8wMDApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gcG9zaXRpdmVJbnQoY29uZmlndXJlZDogdW5rbm93biwga2V5czogRW52S2V5LCBmYWxsYmFjazogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIHRvUG9zaXRpdmVJbnQoY29uZmlndXJlZCkgPz8gdG9Qb3NpdGl2ZUludCh0ZXh0KGtleXMpKSA/PyBmYWxsYmFjaztcbn1cblxuZnVuY3Rpb24gdG9Qb3NpdGl2ZU51bWJlcih2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBcIlwiKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBwYXJzZWQgPSBOdW1iZXIodmFsdWUpO1xuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHBhcnNlZCkgJiYgcGFyc2VkID4gMCA/IHBhcnNlZCA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gdG9Qb3NpdGl2ZUludCh2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHBhcnNlZCA9IHRvUG9zaXRpdmVOdW1iZXIodmFsdWUpO1xuICByZXR1cm4gcGFyc2VkID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBNYXRoLmZsb29yKHBhcnNlZCk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGxpc3Qgc2V0dGluZyB0aHJvdWdoIHtAbGluayBwYXJzZUxpc3R9LCBzbyBhbiBhcnJheSBmcm9tIHR5cGVkXG4gKiBjb25maWcgYW5kIGEgYFwiYSwgYiBjXCJgIGVudiBzdHJpbmcgbm9ybWFsaXplIGlkZW50aWNhbGx5LiBSZXR1cm5zIGBbXWAgd2hlblxuICogbmVpdGhlciBzb3VyY2UgaGFzIGVudHJpZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGVudi5saXN0KGNvbmZpZy5tb2RlbEZhbGxiYWNrcywgXCJXRUJfU0VBUkNIX01PREVMX0ZBTExCQUNLU1wiKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3QoXG4gIGNvbmZpZ3VyZWQ6IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHwgbnVsbCxcbiAga2V5czogRW52S2V5LFxuICB0cmFuc2Zvcm0/OiAoZW50cnk6IHN0cmluZykgPT4gc3RyaW5nLFxuKTogc3RyaW5nW10ge1xuICBjb25zdCBmcm9tQ29uZmlnID0gcGFyc2VMaXN0KGNvbmZpZ3VyZWQsIHRyYW5zZm9ybSk7XG4gIHJldHVybiBmcm9tQ29uZmlnLmxlbmd0aCA+IDAgPyBmcm9tQ29uZmlnIDogcGFyc2VMaXN0KHRleHQoa2V5cyksIHRyYW5zZm9ybSk7XG59XG4iXX0=
|
|
126
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW52LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Vudi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQVVwRCxnRUFBZ0U7QUFDaEUsU0FBUyxXQUFXO0lBQ2xCLE9BQVEsVUFBd0MsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQztBQUN0RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxJQUFJLENBQUMsSUFBWTtJQUMvQixPQUFPLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsSUFBSSxDQUFDLElBQVk7SUFDL0IsTUFBTSxHQUFHLEdBQUcsV0FBVyxFQUFFLENBQUM7SUFDMUIsS0FBSyxNQUFNLEdBQUcsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzNELE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuQyxJQUFJLEtBQUssS0FBSyxJQUFJO1lBQUUsT0FBTyxLQUFLLENBQUM7SUFDbkMsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxNQUFNLENBQUMsVUFBbUIsRUFBRSxJQUFZO0lBQ3RELE9BQU8sVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLFVBQW1CLEVBQUUsSUFBWTtJQUN2RCxPQUFPLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDeEQsQ0FBQztBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLFVBQW1CLEVBQUUsSUFBWSxFQUFFLFFBQWdCO0lBQ2hGLE9BQU8sZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDO0FBQ2xGLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsVUFBbUIsRUFBRSxJQUFZLEVBQUUsUUFBZ0I7SUFDN0UsT0FBTyxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQztBQUM1RSxDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFjO0lBQ3RDLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixPQUFPLE1BQU0sS0FBSyxTQUFTLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDakUsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLEtBQWM7SUFDbkMsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkMsT0FBTyxNQUFNLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDL0QsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsSUFBSSxDQUNsQixVQUF5RCxFQUN6RCxJQUFZLEVBQ1osU0FBcUM7SUFFckMsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNwRCxPQUFPLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDL0UsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmVhZGluZyBjb25maWd1cmF0aW9uIG91dCBvZiB0aGUgZW52aXJvbm1lbnQuXG4gKlxuICogRXZlcnkgcGx1Z2luIGNvbmZpZyBpbiB0aGlzIHJlcG8gcmVzb2x2ZXMgdGhlIHNhbWUgd2F5OiB0YWtlIHRoZSB0eXBlZFxuICogY29uZmlnIHZhbHVlIHdoZW4gdGhlIGNhbGxlciBzZXQgb25lLCBlbHNlIGZhbGwgYmFjayB0byBvbmUgb3IgbW9yZVxuICogZW52aXJvbm1lbnQgdmFyaWFibGVzLCBlbHNlIGEgZGVmYXVsdC4gV3JpdHRlbiBieSBoYW5kIHRoYXQgYmVjb21lcyBhXG4gKiBgY29uZmlnLnggPz8gTnVtYmVyKHByb2Nlc3MuZW52LlgpYCBjaGFpbiBwZXIgZmllbGQsIGFuZCBlYWNoIHBhY2thZ2UgZ3Jld1xuICogaXRzIG93biBgZnJvbUVudmAgLyBgcmVzb2x2ZVBvc2l0aXZlSW50YCBoZWxwZXIgd2l0aCBzbGlnaHRseSBkaWZmZXJlbnRcbiAqIGNvZXJjaW9uIHJ1bGVzLiBUaGVzZSBhcmUgdGhvc2UgaGVscGVycywgb25jZS5cbiAqXG4gKiBCcm93c2VyLXNhZmU6IGBwcm9jZXNzYCBpcyByZWFjaGVkIHRocm91Z2ggYGdsb2JhbFRoaXNgIGFuZCBndWFyZGVkLCBzbyB0aGlzXG4gKiBtb2R1bGUgbmVlZHMgbm8gTm9kZSB0eXBlcyBhbmQgaXMgaW5lcnQgaW4gYSBicm93c2VyIChldmVyeSBsb29rdXAgbWlzc2VzIGFuZFxuICogdGhlIGNhbGxlcidzIGZhbGxiYWNrIGFwcGxpZXMpLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyB0b0Jvb2xlYW4sIHRvTnVtYmVyIH0gZnJvbSBcIi4vb2JqZWN0LnRzXCI7XG5pbXBvcnQgeyBwYXJzZUxpc3QsIHRyaW1Ub051bGwgfSBmcm9tIFwiLi9zdHJpbmcudHNcIjtcblxuLyoqIGBwcm9jZXNzYC1zaGFwZWQgdmlldyBvZmYgYGdsb2JhbFRoaXNgLCBzbyBubyBub2RlIHR5cGVzIGFyZSBuZWVkZWQuICovXG5pbnRlcmZhY2UgUHJvY2Vzc0xpa2Uge1xuICBlbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xufVxuXG4vKiogT25lIGVudiB2YXIgbmFtZSwgb3Igc2V2ZXJhbCB0cmllZCBpbiBvcmRlci4gKi9cbmV4cG9ydCB0eXBlIEVudktleSA9IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4vKiogVGhlIGFtYmllbnQgZW52aXJvbm1lbnQsIG9yIGB7fWAgb2ZmLXByb2Nlc3MgKGEgYnJvd3NlcikuICovXG5mdW5jdGlvbiBlbnZpcm9ubWVudCgpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgcmV0dXJuIChnbG9iYWxUaGlzIGFzIHsgcHJvY2Vzcz86IFByb2Nlc3NMaWtlIH0pLnByb2Nlc3M/LmVudiA/PyB7fTtcbn1cblxuLyoqXG4gKiBUaGUgUFJJTUFSWSAoY3VycmVudCwgbm9uLWRlcHJlY2F0ZWQpIG5hbWUgaW4gYW4ge0BsaW5rIEVudktleX0uXG4gKlxuICogVXNlIHRoaXMgd2hlbiBuYW1pbmcgYSB2YXJpYWJsZSBpbiBhIGxvZyBsaW5lIG9yIGVycm9yIHJhdGhlciB0aGFuIGluZGV4aW5nXG4gKiBga2V5c1swXWA6IGFuIHtAbGluayBFbnZLZXl9IG1heSBiZSBhIGJhcmUgc3RyaW5nLCBhbmQgYFwiVFVOTkVMX1hcIlswXWAgaXMgdGhlXG4gKiBjaGFyYWN0ZXIgYFwiVFwiYCwgd2hpY2ggcHJvZHVjZXMgYSBtZXNzYWdlIG5hbWluZyBhIHZhcmlhYmxlIHRoYXQgZG9lcyBub3RcbiAqIGV4aXN0LiBSZXR1cm5zIGBcIlwiYCBvbmx5IGZvciBhbiBlbXB0eSBsaXN0LCB3aGljaCBubyBjYWxsZXIgc2hvdWxkIGhhdmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGxvZ2dlci53YXJuKGAke2Vudi5uYW1lKEpXVF9TRUNSRVRfRU5WKX0gaXMgbm90IHNldGApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gbmFtZShrZXlzOiBFbnZLZXkpOiBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIGtleXMgPT09IFwic3RyaW5nXCIgPyBrZXlzIDogKGtleXNbMF0gPz8gXCJcIik7XG59XG5cbi8qKlxuICogRmlyc3Qgbm9uLWVtcHR5IHZhbHVlIGFtb25nIGBrZXlzYCwgdHJpbW1lZCwgZWxzZSBgbnVsbGAuXG4gKlxuICogU2V2ZXJhbCBuYW1lcyBmb3Igb25lIHNldHRpbmcgaXMgdGhlIG5vcm0gKGEgcGFja2FnZS1zcGVjaWZpYyB2YXJpYWJsZSBwbHVzXG4gKiB0aGUgRGF0YWJyaWNrcy1zdGFuZGFyZCBvbmUpLCBzbyBga2V5c2AgaXMgb3JkZXItc2Vuc2l0aXZlOiBlYXJsaWVyIG5hbWVzIHdpbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogZW52LnRleHQoW1wiVEVBTVNfQVBQX0lEXCIsIFwiTUlDUk9TT0ZUX0FQUF9JRFwiXSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0KGtleXM6IEVudktleSk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBlbnYgPSBlbnZpcm9ubWVudCgpO1xuICBmb3IgKGNvbnN0IGtleSBvZiB0eXBlb2Yga2V5cyA9PT0gXCJzdHJpbmdcIiA/IFtrZXlzXSA6IGtleXMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRyaW1Ub051bGwoZW52W2tleV0pO1xuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBzdHJpbmcgc2V0dGluZzogYGNvbmZpZ3VyZWRgIHdoZW4gc2V0IGFuZCBub24tZW1wdHksIGVsc2UgdGhlIGZpcnN0XG4gKiBub24tZW1wdHkgdmFyaWFibGUgYW1vbmcgYGtleXNgLCBlbHNlIGBudWxsYC5cbiAqXG4gKiBAZXhhbXBsZVxuICogZW52LnN0cmluZyhjb25maWcuaG9zdCwgXCJTTVRQX0hPU1RcIik7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdHJpbmcoY29uZmlndXJlZDogdW5rbm93biwga2V5czogRW52S2V5KTogc3RyaW5nIHwgbnVsbCB7XG4gIHJldHVybiB0cmltVG9OdWxsKGNvbmZpZ3VyZWQpID8/IHRleHQoa2V5cyk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGJvb2xlYW4gc2V0dGluZyB0aHJvdWdoIHtAbGluayB0b0Jvb2xlYW59LCBzbyB0aGUgbG9vc2Ugc3BlbGxpbmdzIGFuXG4gKiBlbnYgdmFyIGFjdHVhbGx5IGNhcnJpZXMgKGAxYCwgYG9uYCwgYHllc2AsIC4uLikgYXJlIGFjY2VwdGVkLiBSZXR1cm5zXG4gKiBgdW5kZWZpbmVkYCB3aGVuIG5laXRoZXIgc291cmNlIGlzIGludGVycHJldGFibGUsIGxldHRpbmcgdGhlIGNhbGxlciBwaWNrIGFcbiAqIGRlZmF1bHQgd2l0aCBgPz9gLlxuICpcbiAqIEBleGFtcGxlXG4gKiBlbnYuYm9vbGVhbihjb25maWcuZnV6enksIFwiV0VCX1NFQVJDSF9GVVpaWVwiKSA/PyB0cnVlO1xuICovXG5leHBvcnQgZnVuY3Rpb24gYm9vbGVhbihjb25maWd1cmVkOiB1bmtub3duLCBrZXlzOiBFbnZLZXkpOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHRvQm9vbGVhbihjb25maWd1cmVkKSA/PyB0b0Jvb2xlYW4odGV4dChrZXlzKSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHBvc2l0aXZlLW51bWJlciBzZXR0aW5nIHRoYXQgbWF5IGJlIGZyYWN0aW9uYWwgKGEgc2NvcmUgdGhyZXNob2xkLFxuICogYSByYXRpbyk6IGBjb25maWd1cmVkYCB3aGVuIGl0IGlzIGEgZmluaXRlIG51bWJlciBncmVhdGVyIHRoYW4gemVybywgZWxzZSB0aGVcbiAqIGZpcnN0IHZhcmlhYmxlIGFtb25nIGBrZXlzYCB0aGF0IHBhcnNlcyB0aGF0IHdheSwgZWxzZSBgZmFsbGJhY2tgLlxuICpcbiAqIHtAbGluayBwb3NpdGl2ZUludH0gaXMgdGhlIHJpZ2h0IGNob2ljZSBmb3IgYSBjb3VudDsgdGhpcyBvbmUga2VlcHMgdGhlXG4gKiBmcmFjdGlvbiwgc28gYSBgMC40YCB0aHJlc2hvbGQgZG9lcyBub3QgZmxvb3IgdG8gYDBgLlxuICpcbiAqIEBleGFtcGxlXG4gKiBlbnYucG9zaXRpdmVOdW1iZXIoY29uZmlnLmZ1enp5VGhyZXNob2xkLCBcIlNFQVJDSF9GVVpaWV9USFJFU0hPTERcIiwgMC40KTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvc2l0aXZlTnVtYmVyKGNvbmZpZ3VyZWQ6IHVua25vd24sIGtleXM6IEVudktleSwgZmFsbGJhY2s6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiB0b1Bvc2l0aXZlTnVtYmVyKGNvbmZpZ3VyZWQpID8/IHRvUG9zaXRpdmVOdW1iZXIodGV4dChrZXlzKSkgPz8gZmFsbGJhY2s7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHBvc2l0aXZlLWludGVnZXIgc2V0dGluZyAoYSBwb3J0LCB0aW1lb3V0LCBwYWdlIHNpemUsIG9yIGNhcCk6XG4gKiBgY29uZmlndXJlZGAgd2hlbiBpdCBpcyBhIGZpbml0ZSBudW1iZXIgZ3JlYXRlciB0aGFuIHplcm8sIGVsc2UgdGhlIGZpcnN0XG4gKiB2YXJpYWJsZSBhbW9uZyBga2V5c2AgdGhhdCBwYXJzZXMgdGhhdCB3YXksIGVsc2UgYGZhbGxiYWNrYC4gRmxvb3JlZCwgc28gYVxuICogZnJhY3Rpb25hbCB2YWx1ZSBjYW4ndCBsZWFrIGludG8gYSBjb3VudC5cbiAqXG4gKiBBIG5vbi1udW1lcmljIG9yIG5vbi1wb3NpdGl2ZSB2YWx1ZSBpcyB0cmVhdGVkIGFzIGFic2VudCByYXRoZXIgdGhhbiBmYXRhbCAtXG4gKiB0aGVzZSBhcmUgY2VpbGluZ3MgYW5kIHRpbWVvdXRzIHdoZXJlIGEgc2FuZSBkZWZhdWx0IGJlYXRzIGEgYm9vdCBmYWlsdXJlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBlbnYucG9zaXRpdmVJbnQoY29uZmlnLnRpbWVvdXRNcywgXCJTRUFSQ0hfVElNRU9VVF9NU1wiLCAzMF8wMDApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gcG9zaXRpdmVJbnQoY29uZmlndXJlZDogdW5rbm93biwga2V5czogRW52S2V5LCBmYWxsYmFjazogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIHRvUG9zaXRpdmVJbnQoY29uZmlndXJlZCkgPz8gdG9Qb3NpdGl2ZUludCh0ZXh0KGtleXMpKSA/PyBmYWxsYmFjaztcbn1cblxuZnVuY3Rpb24gdG9Qb3NpdGl2ZU51bWJlcih2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHBhcnNlZCA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgcmV0dXJuIHBhcnNlZCAhPT0gdW5kZWZpbmVkICYmIHBhcnNlZCA+IDAgPyBwYXJzZWQgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHRvUG9zaXRpdmVJbnQodmFsdWU6IHVua25vd24pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBwYXJzZWQgPSB0b1Bvc2l0aXZlTnVtYmVyKHZhbHVlKTtcbiAgcmV0dXJuIHBhcnNlZCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogTWF0aC5mbG9vcihwYXJzZWQpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBsaXN0IHNldHRpbmcgdGhyb3VnaCB7QGxpbmsgcGFyc2VMaXN0fSwgc28gYW4gYXJyYXkgZnJvbSB0eXBlZFxuICogY29uZmlnIGFuZCBhIGBcImEsIGIgY1wiYCBlbnYgc3RyaW5nIG5vcm1hbGl6ZSBpZGVudGljYWxseS4gUmV0dXJucyBgW11gIHdoZW5cbiAqIG5laXRoZXIgc291cmNlIGhhcyBlbnRyaWVzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBlbnYubGlzdChjb25maWcubW9kZWxGYWxsYmFja3MsIFwiV0VCX1NFQVJDSF9NT0RFTF9GQUxMQkFDS1NcIik7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0KFxuICBjb25maWd1cmVkOiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXSB8IHVuZGVmaW5lZCB8IG51bGwsXG4gIGtleXM6IEVudktleSxcbiAgdHJhbnNmb3JtPzogKGVudHJ5OiBzdHJpbmcpID0+IHN0cmluZyxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgZnJvbUNvbmZpZyA9IHBhcnNlTGlzdChjb25maWd1cmVkLCB0cmFuc2Zvcm0pO1xuICByZXR1cm4gZnJvbUNvbmZpZy5sZW5ndGggPiAwID8gZnJvbUNvbmZpZyA6IHBhcnNlTGlzdCh0ZXh0KGtleXMpLCB0cmFuc2Zvcm0pO1xufVxuIl19
|
package/lib/src/object.d.ts
CHANGED
|
@@ -2,12 +2,16 @@
|
|
|
2
2
|
* Dependency-free object + iterable utilities.
|
|
3
3
|
*
|
|
4
4
|
* Value guards / coercions / shape types: {@link isRecord} narrows parsed JSON
|
|
5
|
-
* to a record, {@link
|
|
6
|
-
*
|
|
7
|
-
* coerces a date/ISO string/epoch
|
|
5
|
+
* to a record, {@link toNumber} coerces a hand-typed numeral, {@link toBoolean}
|
|
6
|
+
* coerces loose truthy/falsy values, {@link toDuration} parses `1h30m` /
|
|
7
|
+
* `2 milliseconds` to millis, {@link toDate} coerces a date/ISO string/epoch
|
|
8
|
+
* number/relative duration (`toDate` and `toDuration` fall back to each other, so
|
|
9
|
+
* either accepts both readings), {@link optional}
|
|
8
10
|
* spreads a field only when it is present, {@link deepEqual} compares
|
|
9
|
-
* structurally,
|
|
10
|
-
*
|
|
11
|
+
* structurally, {@link isSerializableValue} rejects anything a JSON round trip
|
|
12
|
+
* would lose or coerce, {@link toStableKey} canonicalizes a value so an identity
|
|
13
|
+
* can be derived from it, and {@link NameLike}/{@link NonFunctionKeys} describe
|
|
14
|
+
* object shapes.
|
|
11
15
|
*
|
|
12
16
|
* Iterable helpers: {@link generator} flattens mixed arguments; {@link sequence}
|
|
13
17
|
* wraps source(s) in a lazy, `Array`-compatible {@link Sequence}. Every
|
|
@@ -352,6 +356,88 @@ export type NonFunctionKeys<T> = {
|
|
|
352
356
|
* if (isRecord(parsed)) parsed.foo = 1;
|
|
353
357
|
*/
|
|
354
358
|
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
359
|
+
/** A JSON scalar. `undefined` is deliberately absent - `JSON.stringify` drops it. */
|
|
360
|
+
export type SerializablePrimitive = string | number | boolean | null;
|
|
361
|
+
/**
|
|
362
|
+
* Any value that survives a `JSON.stringify`/`JSON.parse` round trip unchanged.
|
|
363
|
+
*
|
|
364
|
+
* Use it instead of `unknown` on a boundary that will serialize its input - a
|
|
365
|
+
* message payload, a cache entry, a config blob written to disk - so a `Date`,
|
|
366
|
+
* a `Map`, or a class instance is a compile error at the call site rather than a
|
|
367
|
+
* receiver quietly getting a string or `{}`. {@link isSerializableValue} is the
|
|
368
|
+
* runtime half, for input the compiler cannot vouch for.
|
|
369
|
+
*/
|
|
370
|
+
export type SerializableValue = SerializablePrimitive | SerializableValue[] | {
|
|
371
|
+
[key: string]: SerializableValue;
|
|
372
|
+
};
|
|
373
|
+
/**
|
|
374
|
+
* True when `value` survives a JSON round trip with no loss and no coercion.
|
|
375
|
+
*
|
|
376
|
+
* Stricter than "`JSON.stringify` did not throw", because that succeeds while
|
|
377
|
+
* silently CHANGING the value: a `Date` becomes a string, `NaN` and `Infinity`
|
|
378
|
+
* become `null`, a `Map` becomes `{}`, and `undefined` disappears from an object
|
|
379
|
+
* or turns into `null` inside an array. Each of those reaches the far side as
|
|
380
|
+
* something other than what was sent, so all of them are rejected here.
|
|
381
|
+
*
|
|
382
|
+
* Rejected: non-finite numbers, `undefined`, functions, symbols, bigints, class
|
|
383
|
+
* instances and anything else with a prototype other than `Object.prototype` or
|
|
384
|
+
* `null` (`Date`, `Map`, `Set`, `RegExp`, `Buffer`), and any object graph
|
|
385
|
+
* containing a cycle. Accepted: strings, booleans, `null`, finite numbers, plain
|
|
386
|
+
* objects, arrays, and nestings of those.
|
|
387
|
+
*
|
|
388
|
+
* Narrows to {@link SerializableValue} rather than asserting, so it also serves
|
|
389
|
+
* as the validator for untrusted input - a request body, a decoded notification
|
|
390
|
+
* payload - where the answer should be a 400 and not a throw. Never throws.
|
|
391
|
+
*
|
|
392
|
+
* Distinct from {@link deepEqual}'s notion of comparable: that one HANDLES
|
|
393
|
+
* `Date`/`Map`/`Set` structurally, while this one rejects them precisely because
|
|
394
|
+
* JSON cannot carry them.
|
|
395
|
+
*
|
|
396
|
+
* @param ancestors Cycle-detection set for the recursive walk. Internal; callers
|
|
397
|
+
* pass one value.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* isSerializableValue({ a: [1, "x", null] }); // true
|
|
401
|
+
* isSerializableValue({ at: new Date() }); // false - would become a string
|
|
402
|
+
* isSerializableValue(Number.NaN); // false - would become null
|
|
403
|
+
*/
|
|
404
|
+
export declare function isSerializableValue(value: unknown, ancestors?: Set<object>): value is SerializableValue;
|
|
405
|
+
/**
|
|
406
|
+
* Canonical string for a structured value, for deriving a STABLE IDENTITY from
|
|
407
|
+
* it - an advisory-lock id, a channel name, a cache key.
|
|
408
|
+
*
|
|
409
|
+
* The guarantee is two-way, which is what makes it safe to hash: values that
|
|
410
|
+
* should share an identity produce the same string (object key order does not
|
|
411
|
+
* matter), and values that should not are never conflated. Every token carries
|
|
412
|
+
* its type, so `1` and `"1"` differ; a string carries its length, so
|
|
413
|
+
* `["a", "bc"]` and `["ab", "c"]` differ; arrays keep order while object keys
|
|
414
|
+
* are sorted.
|
|
415
|
+
*
|
|
416
|
+
* `JSON.stringify` cannot do this job - key order leaks in, `undefined` vanishes,
|
|
417
|
+
* `1` and `"1"` collide after quoting is stripped, and a cycle throws a
|
|
418
|
+
* `TypeError` naming neither the value nor the caller's intent.
|
|
419
|
+
*
|
|
420
|
+
* Deliberately strict where a silent answer would be a WRONG identity rather
|
|
421
|
+
* than a missing one, since two callers disagreeing about a lock or a channel is
|
|
422
|
+
* invisible until it corrupts something. Throws `TypeError` on a cycle, on a
|
|
423
|
+
* non-finite number (`NaN` is not equal to itself, so it cannot have a stable
|
|
424
|
+
* identity), and on a `function` or `symbol` (no meaningful value identity).
|
|
425
|
+
* `undefined` and `null` are accepted as distinct tokens.
|
|
426
|
+
*
|
|
427
|
+
* `Date` is canonicalized by instant, unlike the hash canonicalizer in
|
|
428
|
+
* `./hash.ts`, which folds every `Date` onto one token. Prefer this function when
|
|
429
|
+
* distinctness is a correctness requirement; prefer `hash.fnvHash` when a short,
|
|
430
|
+
* collision-tolerant digest is enough.
|
|
431
|
+
*
|
|
432
|
+
* @param value - The value to canonicalize.
|
|
433
|
+
* @param seen - Cycle-detection set for the recursive walk. Internal; callers
|
|
434
|
+
* pass one value.
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* toStableKey({ a: 1, b: 2 }) === toStableKey({ b: 2, a: 1 }); // true
|
|
438
|
+
* toStableKey(1) !== toStableKey("1"); // true
|
|
439
|
+
*/
|
|
440
|
+
export declare function toStableKey(value: unknown, seen?: Set<object>): string;
|
|
355
441
|
/**
|
|
356
442
|
* `{ [key]: value }` when `value` is present, otherwise `undefined` - so an
|
|
357
443
|
* absent optional field stays ABSENT when spread, rather than becoming an
|
|
@@ -368,6 +454,69 @@ export declare function isRecord(value: unknown): value is Record<string, unknow
|
|
|
368
454
|
* };
|
|
369
455
|
*/
|
|
370
456
|
export declare function optional<K extends string, V>(key: K, value: V | null | undefined): Record<K, V> | undefined;
|
|
457
|
+
/**
|
|
458
|
+
* Options for {@link toNumber}.
|
|
459
|
+
*
|
|
460
|
+
* Both switches turn OFF a leniency that is helpful for a hand-typed setting but
|
|
461
|
+
* wrong when the string's other characters carry meaning. {@link toDate} and
|
|
462
|
+
* {@link toDuration} disable both, since a space inside `2026 08 02` is a field
|
|
463
|
+
* separator and a percent has no epoch or millisecond reading.
|
|
464
|
+
*/
|
|
465
|
+
export interface ToNumberOptions {
|
|
466
|
+
/**
|
|
467
|
+
* Whether internal digit-group separators are stripped, so `"1,000"` and
|
|
468
|
+
* `"1 000"` read as `1000`. Defaults to `true`.
|
|
469
|
+
*
|
|
470
|
+
* Placement is not validated when enabled, so `"1,00,0"` also reads as `1000`.
|
|
471
|
+
* Disable it when whitespace or a comma delimits FIELDS rather than grouping
|
|
472
|
+
* digits, because stripping them silently fuses those fields into one number.
|
|
473
|
+
*/
|
|
474
|
+
separators?: boolean;
|
|
475
|
+
/**
|
|
476
|
+
* Whether a trailing percent sign divides the result by `100`, so `"25%"` reads
|
|
477
|
+
* as `0.25`. Defaults to `true`.
|
|
478
|
+
*
|
|
479
|
+
* Disable it where a percentage has no meaning, so `"25%"` is a miss rather
|
|
480
|
+
* than a number two orders of magnitude away from what the text says.
|
|
481
|
+
*/
|
|
482
|
+
percent?: boolean;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Coerce a loose numeric value to a real, FINITE `number`, or `undefined` when it
|
|
486
|
+
* carries no numeric meaning.
|
|
487
|
+
*
|
|
488
|
+
* The one place a hand-typed number is interpreted, alongside {@link toBoolean},
|
|
489
|
+
* {@link toDate}, and {@link toDuration}. Reach for it instead of `Number(x)` or a
|
|
490
|
+
* hand-rolled numeric regex: bare `Number` maps `""`, `null`, `[]`, and
|
|
491
|
+
* whitespace to `0` and anything else to `NaN`, so a caller has to re-check the
|
|
492
|
+
* result every time, and ad hoc regexes tend to drift in what they accept.
|
|
493
|
+
*
|
|
494
|
+
* Accepts: a finite `number`; a `bigint`; or a decimal string with an optional
|
|
495
|
+
* leading sign, leading/trailing whitespace, whitespace after the sign,
|
|
496
|
+
* digit-group separators (`"1,000"`, `"1 000"`), a bare fraction (`".5"`), a
|
|
497
|
+
* trailing point (`"1."`), scientific notation (`"1e3"`), and an optional
|
|
498
|
+
* trailing percent sign (`"25%"`, `"1.5 %"`). A trailing `%` divides the parsed
|
|
499
|
+
* value by `100`, so `"25%"` becomes `0.25`.
|
|
500
|
+
*
|
|
501
|
+
* Separators are stripped without validating their placement, so `"1,00,0"` reads
|
|
502
|
+
* as `1000`; this is a coercion for hand-typed configuration, not a locale-aware
|
|
503
|
+
* validator. Anything else, including `NaN`, `Infinity`, an empty or
|
|
504
|
+
* whitespace-only string, `null`, `undefined`, a boolean, multiple signs,
|
|
505
|
+
* malformed exponents, misplaced percent signs, or `"12px"`, returns `undefined`.
|
|
506
|
+
*
|
|
507
|
+
* Returns `undefined` rather than throwing, matching the other coercions, so it
|
|
508
|
+
* composes naturally with `??` fallbacks.
|
|
509
|
+
*
|
|
510
|
+
* @example
|
|
511
|
+
* toNumber("1,000"); // 1000
|
|
512
|
+
* toNumber(" -2.5 "); // -2.5
|
|
513
|
+
* toNumber("1e3"); // 1000
|
|
514
|
+
* toNumber("12.5 %"); // 0.125
|
|
515
|
+
* toNumber(""); // undefined (Number("") would be 0)
|
|
516
|
+
* toNumber("12px"); // undefined
|
|
517
|
+
* toNumber("1 000", { separators: false }); // undefined
|
|
518
|
+
*/
|
|
519
|
+
export declare function toNumber(value: unknown, options?: ToNumberOptions): number | undefined;
|
|
371
520
|
/**
|
|
372
521
|
* Coerce a loose boolean-ish value to a real `boolean`, or `undefined`
|
|
373
522
|
* when it can't be interpreted. Recognizes `true`/`t`/`on`/`1`/`yes`/`y`
|
|
@@ -375,6 +524,45 @@ export declare function optional<K extends string, V>(key: K, value: V | null |
|
|
|
375
524
|
* well as the numbers `1` and `0`.
|
|
376
525
|
*/
|
|
377
526
|
export declare function toBoolean(value: unknown): boolean | undefined;
|
|
527
|
+
/**
|
|
528
|
+
* Options for {@link toDate}.
|
|
529
|
+
*
|
|
530
|
+
* The mirror of {@link ToDurationOptions}: each function can fall back to the
|
|
531
|
+
* other, so each has one switch turning that fallback off.
|
|
532
|
+
*/
|
|
533
|
+
export interface ToDateOptions {
|
|
534
|
+
/**
|
|
535
|
+
* Whether a {@link toDuration} expression is read as an instant relative to
|
|
536
|
+
* now, so `-7d` and `7 days ago` become `now - 7 days`. Defaults to `true`.
|
|
537
|
+
*
|
|
538
|
+
* Set `false` when the value must be a real date and a relative expression
|
|
539
|
+
* should be a miss - a stored timestamp, a user-supplied `Date` header, an
|
|
540
|
+
* `expires_at` field - since a duration silently resolving against the current
|
|
541
|
+
* clock makes the same input mean something different on every call. Also what
|
|
542
|
+
* {@link toDuration} passes when it recurses, so the two cannot bounce a value
|
|
543
|
+
* between them forever.
|
|
544
|
+
*/
|
|
545
|
+
parseDuration?: boolean;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Options for {@link toDuration}.
|
|
549
|
+
*
|
|
550
|
+
* The mirror of {@link ToDateOptions}: each function can fall back to the other,
|
|
551
|
+
* so each has one switch turning that fallback off.
|
|
552
|
+
*/
|
|
553
|
+
export interface ToDurationOptions {
|
|
554
|
+
/**
|
|
555
|
+
* Whether a {@link toDate} value is read as the signed offset from now, so
|
|
556
|
+
* `2026-08-02` becomes however long until (or since) that instant. Defaults to
|
|
557
|
+
* `true`.
|
|
558
|
+
*
|
|
559
|
+
* Set `false` when only a length of time is meaningful - a timeout, a poll
|
|
560
|
+
* interval, a cache TTL - because a date would otherwise yield a plausible but
|
|
561
|
+
* wrong number that also drifts with the clock. Also what {@link toDate} passes
|
|
562
|
+
* when it recurses.
|
|
563
|
+
*/
|
|
564
|
+
parseDate?: boolean;
|
|
565
|
+
}
|
|
378
566
|
/**
|
|
379
567
|
* Coerce a loose duration to MILLISECONDS, or `undefined` when it can't be
|
|
380
568
|
* interpreted.
|
|
@@ -396,14 +584,22 @@ export declare function toBoolean(value: unknown): boolean | undefined;
|
|
|
396
584
|
* returning `1` silently would be worse than returning nothing - which is also
|
|
397
585
|
* what keeps {@link toDate} from mistaking `1 Jan 2026` for a duration.
|
|
398
586
|
*
|
|
587
|
+
* A value that is not a duration at all is offered to {@link toDate} and, when it
|
|
588
|
+
* IS a date, read as the signed offset from now (`date - now`), which makes the
|
|
589
|
+
* two functions inverses: a past instant is negative, a future one positive.
|
|
590
|
+
* `options.parseDate: false` turns that off when only a length of time makes
|
|
591
|
+
* sense - see {@link ToDurationOptions}.
|
|
592
|
+
*
|
|
399
593
|
* @example
|
|
400
594
|
* toDuration("30s"); // 30_000
|
|
401
595
|
* toDuration("1 hour 30 minutes"); // 5_400_000
|
|
402
596
|
* toDuration("-7 days"); // -604_800_000
|
|
403
597
|
* toDuration("2 weeks ago"); // -1_209_600_000
|
|
598
|
+
* toDuration("2026-08-02"); // ms from now to that instant
|
|
599
|
+
* toDuration("2026-08-02", { parseDate: false }); // undefined
|
|
404
600
|
* toDuration("soon"); // undefined
|
|
405
601
|
*/
|
|
406
|
-
export declare function toDuration(value: unknown): number | undefined;
|
|
602
|
+
export declare function toDuration(value: unknown, options?: ToDurationOptions): number | undefined;
|
|
407
603
|
/**
|
|
408
604
|
* Coerce a loose date-ish value to a real `Date`, or `undefined` when it can't be
|
|
409
605
|
* interpreted. Accepts, in this order:
|
|
@@ -423,6 +619,10 @@ export declare function toDuration(value: unknown): number | undefined;
|
|
|
423
619
|
* 1.7 billion years out. Numeric strings are therefore routed to the epoch path,
|
|
424
620
|
* never to `Date.parse`.
|
|
425
621
|
*
|
|
622
|
+
* The duration fallback runs LAST, after `Date.parse`, so a real date is never
|
|
623
|
+
* mistaken for an offset. `options.parseDuration: false` removes it entirely when
|
|
624
|
+
* the value must be an absolute instant - see {@link ToDateOptions}.
|
|
625
|
+
*
|
|
426
626
|
* Like {@link toBoolean} this NEVER throws and returns `undefined` for anything
|
|
427
627
|
* uninterpretable, so a caller decides whether a bad value is fatal, a warning,
|
|
428
628
|
* or a fallback.
|
|
@@ -433,9 +633,10 @@ export declare function toDuration(value: unknown): number | undefined;
|
|
|
433
633
|
* toDate("1785697899"); // seconds -> 2026-08-02T...
|
|
434
634
|
* toDate(1785697899000); // millis -> the same instant
|
|
435
635
|
* toDate("30 days ago"); // now - 30d
|
|
636
|
+
* toDate("30 days ago", { parseDuration: false }); // undefined
|
|
436
637
|
* toDate("nope"); // undefined
|
|
437
638
|
*/
|
|
438
|
-
export declare function toDate(value: unknown): Date | undefined;
|
|
639
|
+
export declare function toDate(value: unknown, options?: ToDateOptions): Date | undefined;
|
|
439
640
|
/**
|
|
440
641
|
* Structural deep-equality with an optional custom comparator.
|
|
441
642
|
*
|