shelving 1.70.0 → 1.71.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/error/ValidationError.js +2 -1
- package/feedback/Feedback.d.ts +2 -16
- package/feedback/Feedback.js +6 -31
- package/package.json +2 -2
- package/schema/AllowSchema.js +2 -2
- package/util/array.d.ts +0 -1
- package/util/array.js +1 -0
- package/util/clone.js +2 -2
- package/util/data.d.ts +8 -1
- package/util/data.js +18 -0
- package/util/date.d.ts +11 -11
- package/util/debug.d.ts +15 -1
- package/util/debug.js +62 -22
- package/util/function.d.ts +2 -0
- package/util/hydrate.js +5 -5
- package/util/number.d.ts +2 -2
- package/util/number.js +5 -1
- package/util/object.d.ts +8 -5
- package/util/object.js +10 -9
- package/util/regexp.d.ts +2 -2
- package/util/set.d.ts +14 -0
- package/util/set.js +17 -0
- package/util/string.d.ts +1 -8
- package/util/string.js +13 -32
- package/util/transform.d.ts +10 -6
- package/util/transform.js +5 -1
- package/util/units.d.ts +8 -8
package/error/ValidationError.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { debug } from "../util/debug.js";
|
|
1
2
|
/** Thrown if a value isn't valid. */
|
|
2
3
|
export class ValidationError extends Error {
|
|
3
4
|
constructor(message, feedback) {
|
|
4
|
-
super(`${message}:\n${feedback.
|
|
5
|
+
super(`${message}:\n${feedback.message} (received ${debug(feedback.details)})`);
|
|
5
6
|
this.feedback = feedback;
|
|
6
7
|
}
|
|
7
8
|
}
|
package/feedback/Feedback.d.ts
CHANGED
|
@@ -12,30 +12,16 @@ import type { ImmutableObject } from "../util/object.js";
|
|
|
12
12
|
*/
|
|
13
13
|
export declare class Feedback {
|
|
14
14
|
/** String feedback message that is safe to show to a user. */
|
|
15
|
-
readonly
|
|
15
|
+
readonly message: string;
|
|
16
16
|
/** Nested details providing deeper feedback. */
|
|
17
17
|
readonly details: ImmutableObject;
|
|
18
18
|
constructor(feedback: string, details?: ImmutableObject);
|
|
19
19
|
/**
|
|
20
20
|
* Map details to a set of string messages.
|
|
21
|
-
* - If a detail is another `Feedback` instance, return its
|
|
21
|
+
* - If a detail is another `Feedback` instance, return its `.message` string.
|
|
22
22
|
* - If a detail is anything else, convert it to string using `toString()`
|
|
23
23
|
*/
|
|
24
24
|
get messages(): ImmutableObject<string>;
|
|
25
|
-
/**
|
|
26
|
-
* Convert to string (equivalent to `message.details`).
|
|
27
|
-
* Returns a string including the main message string and a deeply nested list of child message strings.
|
|
28
|
-
*
|
|
29
|
-
* > Invalid format
|
|
30
|
-
* > - name: Invalid format
|
|
31
|
-
* > - first: Must be string
|
|
32
|
-
* > - value: 123
|
|
33
|
-
* > - last: Must be string
|
|
34
|
-
* > - value: true
|
|
35
|
-
* > - age: Must be number
|
|
36
|
-
* > - value: "abc"
|
|
37
|
-
*/
|
|
38
|
-
toString(): string;
|
|
39
25
|
}
|
|
40
26
|
/** Is an unknown value a `Feedback` instance? */
|
|
41
27
|
export declare const isFeedback: <T extends Feedback>(v: unknown) => v is Feedback;
|
package/feedback/Feedback.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { getString } from "../util/string.js";
|
|
2
|
+
import { mapObject } from "../util/transform.js";
|
|
3
3
|
/**
|
|
4
4
|
* The `Feedback` class represents a feedback message that should be shown to the user.
|
|
5
5
|
* - Basic `Feedback` is neither good nor bad, `SuccessFeedback` indicates good news, and `ErrorFeedback` indicates bad news.
|
|
@@ -13,43 +13,18 @@ import { getTitle } from "../util/string.js";
|
|
|
13
13
|
*/
|
|
14
14
|
export class Feedback {
|
|
15
15
|
constructor(feedback, details = {}) {
|
|
16
|
-
this.
|
|
16
|
+
this.message = feedback;
|
|
17
17
|
this.details = details;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Map details to a set of string messages.
|
|
21
|
-
* - If a detail is another `Feedback` instance, return its
|
|
21
|
+
* - If a detail is another `Feedback` instance, return its `.message` string.
|
|
22
22
|
* - If a detail is anything else, convert it to string using `toString()`
|
|
23
23
|
*/
|
|
24
24
|
get messages() {
|
|
25
|
-
|
|
26
|
-
for (const [k, v] of Object.entries(this.details)) {
|
|
27
|
-
if (isFeedback(v))
|
|
28
|
-
messages[k] = v.feedback;
|
|
29
|
-
else
|
|
30
|
-
messages[k] = getTitle(v);
|
|
31
|
-
}
|
|
32
|
-
return messages;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Convert to string (equivalent to `message.details`).
|
|
36
|
-
* Returns a string including the main message string and a deeply nested list of child message strings.
|
|
37
|
-
*
|
|
38
|
-
* > Invalid format
|
|
39
|
-
* > - name: Invalid format
|
|
40
|
-
* > - first: Must be string
|
|
41
|
-
* > - value: 123
|
|
42
|
-
* > - last: Must be string
|
|
43
|
-
* > - value: true
|
|
44
|
-
* > - age: Must be number
|
|
45
|
-
* > - value: "abc"
|
|
46
|
-
*/
|
|
47
|
-
toString() {
|
|
48
|
-
let output = this.feedback;
|
|
49
|
-
for (const [k, v] of Object.entries(this.details))
|
|
50
|
-
output += `\n- ${k}: ${isFeedback(v) ? v.toString().replace(/\n/g, "\n ") : debug(v)}`;
|
|
51
|
-
return output;
|
|
25
|
+
return mapObject(this.details, _getMessage);
|
|
52
26
|
}
|
|
53
27
|
}
|
|
28
|
+
const _getMessage = (v) => (isFeedback(v) ? v.message : getString(v));
|
|
54
29
|
/** Is an unknown value a `Feedback` instance? */
|
|
55
30
|
export const isFeedback = (v) => v instanceof Feedback;
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"state-management",
|
|
12
12
|
"query-builder"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.
|
|
14
|
+
"version": "1.71.0",
|
|
15
15
|
"repository": "https://github.com/dhoulb/shelving",
|
|
16
16
|
"author": "Dave Houlbrooke <dave@shax.com>",
|
|
17
17
|
"license": "0BSD",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@google-cloud/firestore": "^5.0.2",
|
|
65
|
-
"@types/jest": "^
|
|
65
|
+
"@types/jest": "^28.1.6",
|
|
66
66
|
"@types/react": "^18.0.9",
|
|
67
67
|
"@types/react-dom": "^18.0.4",
|
|
68
68
|
"@typescript-eslint/eslint-plugin": "^5.23.0",
|
package/schema/AllowSchema.js
CHANGED
|
@@ -2,7 +2,7 @@ import { InvalidFeedback } from "../feedback/InvalidFeedback.js";
|
|
|
2
2
|
import { getString } from "../util/string.js";
|
|
3
3
|
import { isArray, isItem } from "../util/array.js";
|
|
4
4
|
import { getOptionalNumber } from "../util/number.js";
|
|
5
|
-
import {
|
|
5
|
+
import { isEntry } from "../util/object.js";
|
|
6
6
|
import { Schema } from "./Schema.js";
|
|
7
7
|
/** Validate a value against a specific set of allowed values. */
|
|
8
8
|
export function validateAllowed(value, allowed) {
|
|
@@ -11,7 +11,7 @@ export function validateAllowed(value, allowed) {
|
|
|
11
11
|
return value;
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
|
-
if (
|
|
14
|
+
if (isEntry(allowed, value))
|
|
15
15
|
return value;
|
|
16
16
|
}
|
|
17
17
|
throw new InvalidFeedback("Unknown value", { value });
|
package/util/array.d.ts
CHANGED
|
@@ -22,7 +22,6 @@ export declare const isItem: <T>(arr: ImmutableArray<T>, item: unknown) => item
|
|
|
22
22
|
/** Things that can be converted to arrays. */
|
|
23
23
|
export declare type PossibleArray<T> = ImmutableArray<T> | Iterable<T>;
|
|
24
24
|
/** Convert an iterable to an array (if its not already an array). */
|
|
25
|
-
export declare function getArray<T>(iterable: ImmutableArray<T> | Iterable<T>): ImmutableArray<T>;
|
|
26
25
|
export declare function getArray<T>(items: PossibleArray<T>): ImmutableArray<T>;
|
|
27
26
|
/**
|
|
28
27
|
* Add an item to an array (immutably).
|
package/util/array.js
CHANGED
|
@@ -8,6 +8,7 @@ export function assertArray(arr) {
|
|
|
8
8
|
}
|
|
9
9
|
/** Is an unknown value an item in a specified array? */
|
|
10
10
|
export const isItem = (arr, item) => arr.includes(item);
|
|
11
|
+
/** Convert an iterable to an array (if its not already an array). */
|
|
11
12
|
export function getArray(items) {
|
|
12
13
|
return isArray(items) ? items : Array.from(items);
|
|
13
14
|
}
|
package/util/clone.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isArray } from "./array.js";
|
|
2
2
|
import { isObject } from "./object.js";
|
|
3
|
-
import { mapArray,
|
|
3
|
+
import { mapArray, mapData } from "./transform.js";
|
|
4
4
|
/** Does an object implement `Cloneable` */
|
|
5
5
|
export const isCloneable = (v) => isObject(v) && typeof v.cloneable === "function";
|
|
6
6
|
/** Shallow clone a value. */
|
|
@@ -27,7 +27,7 @@ export function cloneArray(input, recursor = shallowClone) {
|
|
|
27
27
|
export function cloneObject(input, recursor = shallowClone) {
|
|
28
28
|
if (isCloneable(input))
|
|
29
29
|
return input.clone();
|
|
30
|
-
const output =
|
|
30
|
+
const output = mapData(input, recursor);
|
|
31
31
|
Object.setPrototypeOf(input, Object.getPrototypeOf(input));
|
|
32
32
|
return output;
|
|
33
33
|
}
|
package/util/data.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export declare type Entities<T extends Data = Data> = ImmutableArray<Entity<T>>;
|
|
|
29
29
|
export declare type OptionalEntity<T extends Data = Data> = Entity<T> | null;
|
|
30
30
|
/** Is an unknown value a data object? */
|
|
31
31
|
export declare const isData: <T extends Data>(value: unknown) => value is T;
|
|
32
|
-
/** Turn a data object into an array of
|
|
32
|
+
/** Turn a data object into an array of props. */
|
|
33
33
|
export declare function getProps<T extends Data>(data: T): ImmutableArray<Prop<T>>;
|
|
34
34
|
export declare function getProps<T extends Data>(data: Partial<T>): ImmutableArray<Prop<T>>;
|
|
35
35
|
/** Get the data of a result (returns data or throws `RequiredError` if value is `null` or `undefined`). */
|
|
@@ -142,3 +142,10 @@ export declare type PickProps<T, TT> = Pick<T, {
|
|
|
142
142
|
export declare type OmitProps<T, TT> = Omit<T, {
|
|
143
143
|
[K in keyof T]: T[K] extends TT ? K : never;
|
|
144
144
|
}[keyof T]>;
|
|
145
|
+
/**
|
|
146
|
+
* Format a data object as a string.
|
|
147
|
+
* - Use the custom `.toString()` function if it exists (don't use built in `Object.prototype.toString` because it's useless.
|
|
148
|
+
* - Use `.title` or `.name` or `.id` if they exist and are strings.
|
|
149
|
+
* - Use `Object` otherwise.
|
|
150
|
+
*/
|
|
151
|
+
export declare function formatData(data: Data): string;
|
package/util/data.js
CHANGED
|
@@ -69,3 +69,21 @@ export function setProps(data, props) {
|
|
|
69
69
|
for (const [k, v] of getProps(props))
|
|
70
70
|
data[k] = v;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Format a data object as a string.
|
|
74
|
+
* - Use the custom `.toString()` function if it exists (don't use built in `Object.prototype.toString` because it's useless.
|
|
75
|
+
* - Use `.title` or `.name` or `.id` if they exist and are strings.
|
|
76
|
+
* - Use `Object` otherwise.
|
|
77
|
+
*/
|
|
78
|
+
export function formatData(data) {
|
|
79
|
+
const { toString, name, title, id } = data;
|
|
80
|
+
if (typeof toString === "function" && toString !== Object.prototype.toString)
|
|
81
|
+
return data.toString();
|
|
82
|
+
if (typeof name === "string")
|
|
83
|
+
return name;
|
|
84
|
+
if (typeof title === "string")
|
|
85
|
+
return title;
|
|
86
|
+
if (typeof id === "string")
|
|
87
|
+
return id;
|
|
88
|
+
return "Object";
|
|
89
|
+
}
|
package/util/date.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export declare const days: readonly ["sunday", "monday", "tuesday", "wednesday",
|
|
|
37
37
|
/** Type listing day-of-week strings. */
|
|
38
38
|
export declare type Day = typeof days[number];
|
|
39
39
|
/** Convert a `Date` instance to a day-of-week string like "monday" */
|
|
40
|
-
export declare const getDay: (target?: PossibleDate
|
|
40
|
+
export declare const getDay: (target?: PossibleDate) => Day;
|
|
41
41
|
/** Get a Date representing exactly midnight of the specified date. */
|
|
42
42
|
export declare function getMidnight(target?: PossibleDate): Date;
|
|
43
43
|
/** Get a Date representing midnight on Monday of the specified week. */
|
|
@@ -52,24 +52,24 @@ export declare function addHours(change: number, target?: PossibleDate): Date;
|
|
|
52
52
|
* @param target The date when the thing will happen or did happen.
|
|
53
53
|
* @param current Today's date (or a different date to measure from).
|
|
54
54
|
*/
|
|
55
|
-
export declare const getDuration: (target?: PossibleDate
|
|
55
|
+
export declare const getDuration: (target?: PossibleDate, current?: PossibleDate) => number;
|
|
56
56
|
/** Count the number of seconds until a date. */
|
|
57
|
-
export declare const getSecondsUntil: (target: PossibleDate, current?: PossibleDate
|
|
57
|
+
export declare const getSecondsUntil: (target: PossibleDate, current?: PossibleDate) => number;
|
|
58
58
|
/** Count the number of days ago a date was. */
|
|
59
|
-
export declare const getSecondsAgo: (target: PossibleDate, current?: PossibleDate
|
|
59
|
+
export declare const getSecondsAgo: (target: PossibleDate, current?: PossibleDate) => number;
|
|
60
60
|
/** Count the number of days until a date. */
|
|
61
|
-
export declare const getDaysUntil: (target: PossibleDate, current?: PossibleDate
|
|
61
|
+
export declare const getDaysUntil: (target: PossibleDate, current?: PossibleDate) => number;
|
|
62
62
|
/** Count the number of days ago a date was. */
|
|
63
|
-
export declare const getDaysAgo: (target: PossibleDate, current?: PossibleDate
|
|
63
|
+
export declare const getDaysAgo: (target: PossibleDate, current?: PossibleDate) => number;
|
|
64
64
|
/** Count the number of weeks until a date. */
|
|
65
|
-
export declare const getWeeksUntil: (target: PossibleDate, current?: PossibleDate
|
|
65
|
+
export declare const getWeeksUntil: (target: PossibleDate, current?: PossibleDate) => number;
|
|
66
66
|
/** Count the number of weeks ago a date was. */
|
|
67
|
-
export declare const getWeeksAgo: (target: PossibleDate, current?: PossibleDate
|
|
67
|
+
export declare const getWeeksAgo: (target: PossibleDate, current?: PossibleDate) => number;
|
|
68
68
|
/** Format a date in the browser locale. */
|
|
69
69
|
export declare const formatDate: (date: PossibleDate) => string;
|
|
70
70
|
/** Is a date in the past? */
|
|
71
|
-
export declare const isPast: (target: PossibleDate, current?: PossibleDate
|
|
71
|
+
export declare const isPast: (target: PossibleDate, current?: PossibleDate) => boolean;
|
|
72
72
|
/** Is a date in the future? */
|
|
73
|
-
export declare const isFuture: (target: PossibleDate, current?: PossibleDate
|
|
73
|
+
export declare const isFuture: (target: PossibleDate, current?: PossibleDate) => boolean;
|
|
74
74
|
/** Is a date today (taking into account midnight). */
|
|
75
|
-
export declare const isToday: (target: PossibleDate, current?: PossibleDate
|
|
75
|
+
export declare const isToday: (target: PossibleDate, current?: PossibleDate) => boolean;
|
package/util/debug.d.ts
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
+
import type { ImmutableArray } from "./array.js";
|
|
2
|
+
import type { ImmutableMap } from "./map.js";
|
|
3
|
+
import type { ImmutableSet } from "./set.js";
|
|
4
|
+
import type { ImmutableObject } from "./object.js";
|
|
1
5
|
/** Debug a random value as a string. */
|
|
2
|
-
export declare
|
|
6
|
+
export declare function debug(value: unknown): string;
|
|
7
|
+
/** Debug a string. */
|
|
8
|
+
export declare const debugString: (value: string) => string;
|
|
9
|
+
/** Debug an array. */
|
|
10
|
+
export declare function debugArray(value: ImmutableArray): string;
|
|
11
|
+
/** Debug a set. */
|
|
12
|
+
export declare function debugSet(value: ImmutableSet): string;
|
|
13
|
+
/** Debug a map. */
|
|
14
|
+
export declare function debugMap(value: ImmutableMap): string;
|
|
15
|
+
/** Debug an object. */
|
|
16
|
+
export declare function debugObject(value: ImmutableObject): string;
|
package/util/debug.js
CHANGED
|
@@ -1,24 +1,64 @@
|
|
|
1
|
+
/* eslint-disable no-control-regex */
|
|
1
2
|
/** Debug a random value as a string. */
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
3
|
+
export function debug(value) {
|
|
4
|
+
if (value === null)
|
|
5
|
+
return "null";
|
|
6
|
+
if (value === undefined)
|
|
7
|
+
return "undefined";
|
|
8
|
+
if (typeof value === "boolean")
|
|
9
|
+
return value ? "true" : "false";
|
|
10
|
+
if (typeof value === "string")
|
|
11
|
+
return debugString(value);
|
|
12
|
+
if (typeof value === "number")
|
|
13
|
+
return value.toString();
|
|
14
|
+
if (typeof value === "symbol")
|
|
15
|
+
return value.toString();
|
|
16
|
+
if (typeof value === "function")
|
|
17
|
+
return `function ${value.name || ""}()`;
|
|
18
|
+
if (typeof value === "object") {
|
|
19
|
+
if (value instanceof Date)
|
|
20
|
+
return value.toISOString();
|
|
21
|
+
if (value instanceof Error)
|
|
22
|
+
return value.toString();
|
|
23
|
+
if (value instanceof Array)
|
|
24
|
+
return debugArray(value);
|
|
25
|
+
if (value instanceof Map)
|
|
26
|
+
return debugMap(value);
|
|
27
|
+
if (value instanceof Set)
|
|
28
|
+
return debugSet(value);
|
|
29
|
+
return debugObject(value);
|
|
30
|
+
}
|
|
31
|
+
return typeof value;
|
|
32
|
+
}
|
|
33
|
+
/** Debug a string. */
|
|
34
|
+
export const debugString = (value) => `"${value.replace(MATCH_ESCAPES, _debugChar)}"`;
|
|
35
|
+
const MATCH_ESCAPES = /[\x00-\x08\x0B-\x1F\x7F-\x9F"\\]/g; // Match control characters, `"` double quote, `\` backslash.
|
|
36
|
+
const ESCAPES = { '"': '\\"', "\\": "\\\\", "\r": "\\r", "\n": "\\n", "\t": "\\t", "\b": "\\b", "\f": "\\f", "\v": "\\v" };
|
|
37
|
+
const _debugChar = (char) => ESCAPES[char] || `\\x${char.charCodeAt(0).toString(16).padStart(2, "00")}`;
|
|
38
|
+
/** Debug an array. */
|
|
39
|
+
export function debugArray(value) {
|
|
22
40
|
const prototype = Object.getPrototypeOf(value);
|
|
23
|
-
|
|
24
|
-
}
|
|
41
|
+
const name = prototype === Array ? "" : prototype.name || "";
|
|
42
|
+
return `${name ? `${name} ` : ""}${value.length ? `[\n\t${value.map(debug).join(",\n\t")}\n]` : "[]"}`;
|
|
43
|
+
}
|
|
44
|
+
/** Debug a set. */
|
|
45
|
+
export function debugSet(value) {
|
|
46
|
+
const prototype = Object.getPrototypeOf(value);
|
|
47
|
+
const name = prototype === Array ? "" : prototype.name || "Set";
|
|
48
|
+
return `${name}(value.size) ${value.size ? `{\n\t${Array.from(value).map(debug).join(",\n\t")}\n}` : "{}"}`;
|
|
49
|
+
}
|
|
50
|
+
/** Debug a map. */
|
|
51
|
+
export function debugMap(value) {
|
|
52
|
+
const prototype = Object.getPrototypeOf(value);
|
|
53
|
+
const name = prototype === Array ? "" : prototype.name || "Map";
|
|
54
|
+
return `${name}(value.size) ${value.size ? `{\n\t${Array.from(value).map(_debugProp).join(",\n\t")}\n}` : "{}"}`;
|
|
55
|
+
}
|
|
56
|
+
/** Debug an object. */
|
|
57
|
+
export function debugObject(value) {
|
|
58
|
+
const prototype = Object.getPrototypeOf(value) || Object;
|
|
59
|
+
const name = prototype === Object ? "" : prototype.name || "";
|
|
60
|
+
const props = Object.entries(value).map(_debugProp);
|
|
61
|
+
return `${name ? `${name} ` : ""}${props.length ? `{\n\t${props.join(",\n\t")}\n}` : "{}"}`;
|
|
62
|
+
}
|
|
63
|
+
/** Debug a prop. */
|
|
64
|
+
const _debugProp = ([key, value]) => `${debug(key)}: ${debug(value)}`;
|
package/util/function.d.ts
CHANGED
package/util/hydrate.js
CHANGED
|
@@ -2,7 +2,7 @@ import { AssertionError } from "../error/AssertionError.js";
|
|
|
2
2
|
import { isArray } from "./array.js";
|
|
3
3
|
import { isData } from "./data.js";
|
|
4
4
|
import { isPlainObject } from "./object.js";
|
|
5
|
-
import { mapArray,
|
|
5
|
+
import { mapArray, mapData } from "./transform.js";
|
|
6
6
|
/**
|
|
7
7
|
* Deeply dehydrate a class instance based on a set of `Hydrations`
|
|
8
8
|
* - Dehydration allows you to pass class instances from a server back to a client.
|
|
@@ -38,11 +38,11 @@ export class Hydrator {
|
|
|
38
38
|
return mapArray(value, this);
|
|
39
39
|
if (isPlainObject(value)) {
|
|
40
40
|
if (!isDehydrated(value))
|
|
41
|
-
return
|
|
41
|
+
return mapData(value, this);
|
|
42
42
|
const { _type, ...props } = value;
|
|
43
43
|
const hydration = this._hydrations[_type];
|
|
44
44
|
if (hydration)
|
|
45
|
-
return { __proto__: hydration.prototype, ...
|
|
45
|
+
return { __proto__: hydration.prototype, ...mapData(props, this) };
|
|
46
46
|
throw new AssertionError(`Cannot hydrate "${_type}" object`, value);
|
|
47
47
|
}
|
|
48
48
|
return value;
|
|
@@ -57,11 +57,11 @@ export class Dehydrator {
|
|
|
57
57
|
if (isArray(value))
|
|
58
58
|
return mapArray(value, this);
|
|
59
59
|
if (isPlainObject(value))
|
|
60
|
-
return
|
|
60
|
+
return mapData(value, this);
|
|
61
61
|
if (isData(value)) {
|
|
62
62
|
for (const [_type, hydration] of Object.entries(this._hydrations))
|
|
63
63
|
if (value instanceof hydration)
|
|
64
|
-
return { _type, ...
|
|
64
|
+
return { _type, ...mapData(value, this) };
|
|
65
65
|
throw new AssertionError(`Cannot dehydrate object`, value);
|
|
66
66
|
}
|
|
67
67
|
return value;
|
package/util/number.d.ts
CHANGED
|
@@ -66,9 +66,9 @@ export declare const truncateNumber: (num: number, precision?: number) => number
|
|
|
66
66
|
*
|
|
67
67
|
* @returns The number formatted as a string in the browser's current locale.
|
|
68
68
|
*/
|
|
69
|
-
export declare
|
|
69
|
+
export declare function formatNumber(num: number, maxPrecision?: number, minPrecision?: number): string;
|
|
70
70
|
/** Format a number with a short suffix. */
|
|
71
|
-
export declare const formatQuantity: (num: number, suffix: string, maxPrecision?: number
|
|
71
|
+
export declare const formatQuantity: (num: number, suffix: string, maxPrecision?: number, minPrecision?: number) => string;
|
|
72
72
|
/** Format a number with a longer full-word suffix. */
|
|
73
73
|
export declare function formatFullQuantity(num: number, singular: string, plural: string, maxPrecision?: number, minPrecision?: number): string;
|
|
74
74
|
/**
|
package/util/number.js
CHANGED
|
@@ -93,7 +93,11 @@ export const truncateNumber = (num, precision = 0) => Math.trunc(num * 10 ** pre
|
|
|
93
93
|
*
|
|
94
94
|
* @returns The number formatted as a string in the browser's current locale.
|
|
95
95
|
*/
|
|
96
|
-
export
|
|
96
|
+
export function formatNumber(num, maxPrecision = 4, minPrecision = 0) {
|
|
97
|
+
if (!Number.isFinite(num))
|
|
98
|
+
return Number.isNaN(num) ? "None" : "Infinity";
|
|
99
|
+
return new Intl.NumberFormat(undefined, { maximumFractionDigits: maxPrecision, minimumFractionDigits: minPrecision }).format(num);
|
|
100
|
+
}
|
|
97
101
|
/** Format a number with a short suffix. */
|
|
98
102
|
export const formatQuantity = (num, suffix, maxPrecision, minPrecision) => `${formatNumber(num, maxPrecision, minPrecision)}${suffix}`;
|
|
99
103
|
/** Format a number with a longer full-word suffix. */
|
package/util/object.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ImmutableArray } from "./array.js";
|
|
2
2
|
import type { NotString } from "./string.js";
|
|
3
|
+
import type { Entry } from "./entry.js";
|
|
3
4
|
/** Readonly object with string keys. */
|
|
4
5
|
export declare type ImmutableObject<T = unknown> = {
|
|
5
6
|
readonly [key: string | number]: T;
|
|
@@ -23,11 +24,7 @@ export declare const isPlainObject: <T extends ImmutableObject<unknown>>(value:
|
|
|
23
24
|
/** Assert that a value is a plain object */
|
|
24
25
|
export declare function assertPlainObject<T extends ImmutableObject>(value: T | unknown): asserts value is T;
|
|
25
26
|
/** Is an unknown string an own prop of an object. */
|
|
26
|
-
export declare const
|
|
27
|
-
/** Assert that a value is an object with a specific property. */
|
|
28
|
-
export declare function assertKey<K extends string | number | symbol, T extends {
|
|
29
|
-
[L in K]: unknown;
|
|
30
|
-
}>(value: T | unknown, key: K): asserts value is T;
|
|
27
|
+
export declare const isEntry: <T extends ImmutableObject<unknown>>(obj: T, key: unknown) => key is keyof T;
|
|
31
28
|
/**
|
|
32
29
|
* Add a key/value entry to a map-like object (immutably).
|
|
33
30
|
*
|
|
@@ -66,6 +63,12 @@ export declare function withoutEntry<T>(input: ImmutableObject<T>, key: string,
|
|
|
66
63
|
* - If every entry already exists and has the exact same input object will be returned.
|
|
67
64
|
*/
|
|
68
65
|
export declare function withoutEntries<T>(input: ImmutableObject<T>, keys: Iterable<string> & NotString): ImmutableObject<T>;
|
|
66
|
+
/**
|
|
67
|
+
* Get the entries of an object.
|
|
68
|
+
*
|
|
69
|
+
* @param obj The target object.
|
|
70
|
+
*/
|
|
71
|
+
export declare const getEntries: <T>(obj: ImmutableObject<T>) => ImmutableArray<Entry<T>>;
|
|
69
72
|
/**
|
|
70
73
|
* Set a key/value entry on a map-like object (by reference).
|
|
71
74
|
*
|
package/util/object.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AssertionError } from "../error/AssertionError.js";
|
|
2
|
-
import { setProp, setProps, withProp, withProps } from "./data.js";
|
|
2
|
+
import { getProps, setProp, setProps, withProp, withProps } from "./data.js";
|
|
3
3
|
/**
|
|
4
4
|
* Is a value an unknown object?
|
|
5
5
|
* - This is a TypeScript assertion object that asserts the value extends `ImmutableObject`
|
|
@@ -19,12 +19,7 @@ export function assertPlainObject(value) {
|
|
|
19
19
|
throw new AssertionError(`Must be plain object`, value);
|
|
20
20
|
}
|
|
21
21
|
/** Is an unknown string an own prop of an object. */
|
|
22
|
-
export const
|
|
23
|
-
/** Assert that a value is an object with a specific property. */
|
|
24
|
-
export function assertKey(value, key) {
|
|
25
|
-
if (!isObject(value) || !(key in value))
|
|
26
|
-
throw new AssertionError(`Must be object with prop "${key}"`, value);
|
|
27
|
-
}
|
|
22
|
+
export const isEntry = (obj, key) => (typeof key === "string" || typeof key === "number" || typeof key === "symbol") && Object.prototype.hasOwnProperty.call(obj, key);
|
|
28
23
|
/**
|
|
29
24
|
* Add a key/value entry to a map-like object (immutably).
|
|
30
25
|
*
|
|
@@ -53,7 +48,7 @@ export const withEntries = withProps;
|
|
|
53
48
|
* - If `key` doesn't already exist in `obj` then the exact same input object will be returned.
|
|
54
49
|
*/
|
|
55
50
|
export function withoutEntry(input, key, value) {
|
|
56
|
-
if (
|
|
51
|
+
if (isEntry(input, key) && (value === undefined || input[key] === value)) {
|
|
57
52
|
const { [key]: unused, ...output } = input;
|
|
58
53
|
return output;
|
|
59
54
|
}
|
|
@@ -72,12 +67,18 @@ export function withoutEntries(input, keys) {
|
|
|
72
67
|
let changed = false;
|
|
73
68
|
const output = { ...input };
|
|
74
69
|
for (const key of keys)
|
|
75
|
-
if (
|
|
70
|
+
if (isEntry(input, key)) {
|
|
76
71
|
delete output[key];
|
|
77
72
|
changed = true;
|
|
78
73
|
}
|
|
79
74
|
return changed ? output : input;
|
|
80
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Get the entries of an object.
|
|
78
|
+
*
|
|
79
|
+
* @param obj The target object.
|
|
80
|
+
*/
|
|
81
|
+
export const getEntries = getProps;
|
|
81
82
|
/**
|
|
82
83
|
* Set a key/value entry on a map-like object (by reference).
|
|
83
84
|
*
|
package/util/regexp.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare const isRegExp: <T extends RegExp>(v: unknown) => v is T;
|
|
|
16
16
|
/** Assert that an unknown value is a `RegExp` instance. */
|
|
17
17
|
export declare function assertRegExp<T extends RegExp>(v: T | unknown): asserts v is T;
|
|
18
18
|
/** Convert a string to a regular expression that matches that string. */
|
|
19
|
-
export declare const getRegExp: (pattern: PossibleRegExp, flags?: string
|
|
19
|
+
export declare const getRegExp: (pattern: PossibleRegExp, flags?: string) => RegExp;
|
|
20
20
|
/** Convert a regular expression to its string source. */
|
|
21
21
|
export declare const getRegExpSource: (regexp: PossibleRegExp) => string;
|
|
22
22
|
/** Escape special characters in a string regular expression. */
|
|
@@ -35,7 +35,7 @@ export interface NamedRegExp<T extends NamedRegExpData = NamedRegExpData> extend
|
|
|
35
35
|
exec(input: string): NamedRegExpArray<T> | null;
|
|
36
36
|
}
|
|
37
37
|
/** Create a named regular expression (note: this is unsafe). */
|
|
38
|
-
export declare const getNamedRegExp: <T extends NamedRegExpData>(pattern: string | RegExp, flags?: string
|
|
38
|
+
export declare const getNamedRegExp: <T extends NamedRegExpData>(pattern: string | RegExp, flags?: string) => NamedRegExp<T>;
|
|
39
39
|
/** Create regular expression that matches a block of content (possibly asserting that it contains named match groups). */
|
|
40
40
|
export declare function getBlockRegExp<T extends NamedRegExpData>(middle: PossibleRegExp, end?: PossibleRegExp, start?: PossibleRegExp, flags?: string): NamedRegExp<T>;
|
|
41
41
|
export declare function getBlockRegExp(middle: PossibleRegExp, end?: PossibleRegExp, start?: PossibleRegExp, flags?: string): RegExp;
|
package/util/set.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** `Set` that cannot be changed. */
|
|
2
|
+
export declare type ImmutableSet<T = unknown> = ReadonlySet<T>;
|
|
3
|
+
/** `Set` that can be changed. */
|
|
4
|
+
export declare type MutableSet<T = unknown> = Set<T>;
|
|
5
|
+
/** Things that can be converted to sets. */
|
|
6
|
+
export declare type PossibleSet<T> = ImmutableSet<T> | Iterable<T>;
|
|
7
|
+
/** Is an unknown value a set? */
|
|
8
|
+
export declare const isSet: <T extends ImmutableSet<unknown>>(v: unknown) => v is T;
|
|
9
|
+
/** Assert that a value is a `Set` instance. */
|
|
10
|
+
export declare function assertSet<T extends ImmutableSet>(v: T | unknown): asserts v is T;
|
|
11
|
+
/** Convert an iterable to a `Set` (if it's already a `Set` it passes through unchanged). */
|
|
12
|
+
export declare function getSet<T>(iterable: PossibleSet<T>): ImmutableSet<T>;
|
|
13
|
+
/** Apply a limit to a set. */
|
|
14
|
+
export declare function limitSet<T>(set: ImmutableSet<T>, limit: number): ImmutableSet<T>;
|
package/util/set.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AssertionError } from "../error/AssertionError.js";
|
|
2
|
+
import { limitItems } from "./iterate.js";
|
|
3
|
+
/** Is an unknown value a set? */
|
|
4
|
+
export const isSet = (v) => v instanceof Set;
|
|
5
|
+
/** Assert that a value is a `Set` instance. */
|
|
6
|
+
export function assertSet(v) {
|
|
7
|
+
if (!isSet(v))
|
|
8
|
+
throw new AssertionError(`Must be set`, v);
|
|
9
|
+
}
|
|
10
|
+
/** Convert an iterable to a `Set` (if it's already a `Set` it passes through unchanged). */
|
|
11
|
+
export function getSet(iterable) {
|
|
12
|
+
return isSet(iterable) ? iterable : new Set(iterable);
|
|
13
|
+
}
|
|
14
|
+
/** Apply a limit to a set. */
|
|
15
|
+
export function limitSet(set, limit) {
|
|
16
|
+
return limit > set.size ? set : new Set(limitItems(set, limit));
|
|
17
|
+
}
|
package/util/string.d.ts
CHANGED
|
@@ -19,13 +19,6 @@ export declare const NNBSP = "\u202F";
|
|
|
19
19
|
export declare const isString: (v: unknown) => v is string;
|
|
20
20
|
/** Assert that a value is a string. */
|
|
21
21
|
export declare function assertString(value: unknown): asserts value is string;
|
|
22
|
-
/**
|
|
23
|
-
* Convert an unknown value into a string for internal use.
|
|
24
|
-
* - Objects use `obj.toString()` as long as it's not the default `Object.toString()` which is garbage.
|
|
25
|
-
* - Primitives return `true`, `false`, `null`, `undefined`
|
|
26
|
-
* - Numbers return the stringified number.
|
|
27
|
-
*/
|
|
28
|
-
export declare function getString(value: unknown): string;
|
|
29
22
|
/**
|
|
30
23
|
* Convert an unknown value into a title string for user-facing use.
|
|
31
24
|
* - Strings return the string.
|
|
@@ -39,7 +32,7 @@ export declare function getString(value: unknown): string;
|
|
|
39
32
|
* - Falsy values like `null` and `undefined` return `"None"`
|
|
40
33
|
* - Everything else returns `"Unknown"`
|
|
41
34
|
*/
|
|
42
|
-
export declare function
|
|
35
|
+
export declare function getString(value: unknown): string;
|
|
43
36
|
/** Concatenate an iterable set of strings together. */
|
|
44
37
|
export declare const joinStrings: (strs: Iterable<string> & NotString, joiner?: string) => string;
|
|
45
38
|
/**
|
package/util/string.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-control-regex */
|
|
2
2
|
import { AssertionError } from "../error/AssertionError.js";
|
|
3
3
|
import { formatDate, isDate } from "./date.js";
|
|
4
|
-
import { isData } from "./data.js";
|
|
4
|
+
import { formatData, isData } from "./data.js";
|
|
5
5
|
import { getArray, isArray } from "./array.js";
|
|
6
6
|
import { formatNumber, isBetween } from "./number.js";
|
|
7
7
|
/** Non-breaking space. */
|
|
@@ -17,25 +17,6 @@ export function assertString(value) {
|
|
|
17
17
|
if (typeof value !== "string")
|
|
18
18
|
throw new AssertionError(`Must be string`, value);
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Convert an unknown value into a string for internal use.
|
|
22
|
-
* - Objects use `obj.toString()` as long as it's not the default `Object.toString()` which is garbage.
|
|
23
|
-
* - Primitives return `true`, `false`, `null`, `undefined`
|
|
24
|
-
* - Numbers return the stringified number.
|
|
25
|
-
*/
|
|
26
|
-
export function getString(value) {
|
|
27
|
-
if (typeof value === "string")
|
|
28
|
-
return value;
|
|
29
|
-
if (typeof value === "number")
|
|
30
|
-
return value.toString();
|
|
31
|
-
if (typeof value === "object")
|
|
32
|
-
return value === null ? "null" : typeof value.toString === "function" && value.toString !== Object.prototype.toString ? value.toString() : "object";
|
|
33
|
-
if (typeof value === "boolean")
|
|
34
|
-
return value.toString();
|
|
35
|
-
if (typeof value === "function")
|
|
36
|
-
return value.name || "function";
|
|
37
|
-
return typeof value; // "symbol" etc.
|
|
38
|
-
}
|
|
39
20
|
/**
|
|
40
21
|
* Convert an unknown value into a title string for user-facing use.
|
|
41
22
|
* - Strings return the string.
|
|
@@ -49,25 +30,25 @@ export function getString(value) {
|
|
|
49
30
|
* - Falsy values like `null` and `undefined` return `"None"`
|
|
50
31
|
* - Everything else returns `"Unknown"`
|
|
51
32
|
*/
|
|
52
|
-
export function
|
|
53
|
-
if (
|
|
54
|
-
return
|
|
33
|
+
export function getString(value) {
|
|
34
|
+
if (value === null || value === undefined)
|
|
35
|
+
return "None";
|
|
55
36
|
if (typeof value === "boolean")
|
|
56
37
|
return value ? "Yes" : "No";
|
|
38
|
+
if (typeof value === "string")
|
|
39
|
+
return value || "None";
|
|
57
40
|
if (typeof value === "number")
|
|
58
41
|
return formatNumber(value);
|
|
42
|
+
if (typeof value === "symbol")
|
|
43
|
+
return value.description || "Symbol";
|
|
44
|
+
if (typeof value === "function")
|
|
45
|
+
return "Function";
|
|
59
46
|
if (isDate(value))
|
|
60
47
|
return formatDate(value);
|
|
61
48
|
if (isArray(value))
|
|
62
|
-
return value.map(
|
|
63
|
-
if (isData(value))
|
|
64
|
-
|
|
65
|
-
return getTitle(value.name);
|
|
66
|
-
if ("title" in value)
|
|
67
|
-
return getTitle(value.title);
|
|
68
|
-
}
|
|
69
|
-
if (!value)
|
|
70
|
-
return "None";
|
|
49
|
+
return value.map(getString).join(", ");
|
|
50
|
+
if (isData(value))
|
|
51
|
+
return formatData(value);
|
|
71
52
|
return "Unknown";
|
|
72
53
|
}
|
|
73
54
|
/** Concatenate an iterable set of strings together. */
|
package/util/transform.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Data, Value, Prop } from "./data.js";
|
|
2
2
|
import type { Entry } from "./entry.js";
|
|
3
|
-
import
|
|
3
|
+
import { ImmutableObject } from "./object.js";
|
|
4
4
|
import { ArrayType, ImmutableArray } from "./array.js";
|
|
5
5
|
/** Object that transforms an input value into an output value with its `transform()` method. */
|
|
6
6
|
export interface Transformable<I, O> {
|
|
@@ -36,15 +36,19 @@ export declare function transformProps<T extends Data>(data: T, transforms: Prop
|
|
|
36
36
|
export declare function mapEntries<I, O>(entries: Iterable<Entry<I>>, transformer: (v: I) => O): Iterable<Entry<O>>;
|
|
37
37
|
export declare function mapEntries<I, O>(entries: Iterable<Entry<I>>, transformer: Transformer<I, O>): Iterable<Entry<O>>;
|
|
38
38
|
/**
|
|
39
|
-
* Transform the _values_ of
|
|
39
|
+
* Transform the _values_ of a map-like object using a transformer.
|
|
40
40
|
* @return New object after transforming its entries.
|
|
41
41
|
*/
|
|
42
|
-
export declare function mapObject<T extends Data>(obj: T, transformer: Transformer<Value<T>, Value<T>>): T;
|
|
43
|
-
export declare function mapObject<I extends Data, O extends {
|
|
44
|
-
[K in keyof I]: unknown;
|
|
45
|
-
}>(obj: I, transformer: Transformer<Value<I>, Value<O>>): O;
|
|
46
42
|
export declare function mapObject<I, O>(obj: ImmutableObject<I>, transformer: (v: I) => O): ImmutableObject<O>;
|
|
47
43
|
export declare function mapObject<I, O>(obj: ImmutableObject<I>, transformer: Transformer<I, O>): ImmutableObject<O>;
|
|
44
|
+
/**
|
|
45
|
+
* Transform the _values_ of an data object using a transformer.
|
|
46
|
+
* @return New object after transforming its entries.
|
|
47
|
+
*/
|
|
48
|
+
export declare function mapData<T extends Data>(data: T, transformer: Transformer<Value<T>, Value<T>>): T;
|
|
49
|
+
export declare function mapData<I extends Data, O extends {
|
|
50
|
+
[K in keyof I]: unknown;
|
|
51
|
+
}>(data: I, transformer: Transformer<Value<I>, Value<O>>): O;
|
|
48
52
|
/**
|
|
49
53
|
* Map an iterable set of items using a transformer.
|
|
50
54
|
* @yield Transformed items after calling `transformer()` on each.
|
package/util/transform.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isFunction } from "./function.js";
|
|
2
2
|
import { getProps, isData } from "./data.js";
|
|
3
|
+
import { getEntries } from "./object.js";
|
|
3
4
|
/** Is an unknown value a derivable. */
|
|
4
5
|
export const isTransformable = (v) => isData(v) && typeof v.transform === "function";
|
|
5
6
|
export function transform(input, transformer) {
|
|
@@ -25,7 +26,10 @@ export function* mapEntries(entries, transformer) {
|
|
|
25
26
|
yield [k, transform(v, transformer)];
|
|
26
27
|
}
|
|
27
28
|
export function mapObject(obj, transformer) {
|
|
28
|
-
return Object.fromEntries(mapEntries(
|
|
29
|
+
return Object.fromEntries(mapEntries(getEntries(obj), transformer));
|
|
30
|
+
}
|
|
31
|
+
export function mapData(data, transformer) {
|
|
32
|
+
return mapObject(data, transformer);
|
|
29
33
|
}
|
|
30
34
|
export function* mapItems(items, transformer) {
|
|
31
35
|
for (const item of items)
|
package/util/units.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export declare function convertUnits(num: number, from: UnitReference, to: UnitR
|
|
|
45
45
|
* @param unit String reference for a unit of measure e.g. `kilometer`
|
|
46
46
|
* @param maxPrecision Number of decimal places to round the number to e.g. `2`
|
|
47
47
|
*/
|
|
48
|
-
export declare const formatUnits: (num: number, unit: UnitReference, maxPrecision?: number
|
|
48
|
+
export declare const formatUnits: (num: number, unit: UnitReference, maxPrecision?: number, minPrecision?: number) => string;
|
|
49
49
|
/**
|
|
50
50
|
* Format a number with a given unit of measure, e.g. `12 kilograms` or `29.5 liters` or `1 degree`
|
|
51
51
|
*
|
|
@@ -53,16 +53,16 @@ export declare const formatUnits: (num: number, unit: UnitReference, maxPrecisio
|
|
|
53
53
|
* @param unit String reference for a unit of measure e.g. `kilometer`
|
|
54
54
|
* @param maxPrecision Number of decimal places to round the number to e.g. `2`
|
|
55
55
|
*/
|
|
56
|
-
export declare const formatFullUnits: (num: number, unit: UnitReference, maxPrecision?: number
|
|
56
|
+
export declare const formatFullUnits: (num: number, unit: UnitReference, maxPrecision?: number, minPrecision?: number) => string;
|
|
57
57
|
/**
|
|
58
58
|
* Format a percentage.
|
|
59
59
|
* - Combines `getPercent()` and `formatUnits()` for convenience.
|
|
60
60
|
*/
|
|
61
|
-
export declare const formatPercent: (numerator: number, denumerator: number, maxPrecision?: number
|
|
61
|
+
export declare const formatPercent: (numerator: number, denumerator: number, maxPrecision?: number, minPrecision?: number) => string;
|
|
62
62
|
/** Format a full description of a duration of time using the most reasonable units e.g. `5 years` or `1 week` or `4 minutes` or `12 milliseconds`. */
|
|
63
|
-
export declare const formatFullDuration: (ms: number, maxPrecision?: number
|
|
63
|
+
export declare const formatFullDuration: (ms: number, maxPrecision?: number, minPrecision?: number) => string;
|
|
64
64
|
/** Format a description of a duration of time using the most reasonable units e.g. `5y` or `4m` or `12ms`. */
|
|
65
|
-
export declare const formatDuration: (ms: number, maxPrecision?: number
|
|
65
|
+
export declare const formatDuration: (ms: number, maxPrecision?: number, minPrecision?: number) => string;
|
|
66
66
|
/**
|
|
67
67
|
* Return full description of the gap between two dates, e.g. `in 10 days` or `2 hours ago`
|
|
68
68
|
*
|
|
@@ -76,7 +76,7 @@ export declare function formatFullWhen(target: PossibleDate, current?: PossibleD
|
|
|
76
76
|
* @param target The date when the thing happened.
|
|
77
77
|
* @param current Today's date (or a different date to measure from).
|
|
78
78
|
*/
|
|
79
|
-
export declare const formatFullAgo: (target: PossibleDate, current?: PossibleDate
|
|
79
|
+
export declare const formatFullAgo: (target: PossibleDate, current?: PossibleDate) => string;
|
|
80
80
|
/**
|
|
81
81
|
* Compact how long until a date happens, e.g. `in 10d` or `2h ago` or `in 1w`
|
|
82
82
|
*
|
|
@@ -90,11 +90,11 @@ export declare function formatWhen(target: PossibleDate, current?: PossibleDate)
|
|
|
90
90
|
* @param target The date when the thing will happen.
|
|
91
91
|
* @param current Today's date (or a different date to measure from).
|
|
92
92
|
*/
|
|
93
|
-
export declare const formatUntil: (target: PossibleDate, current?: PossibleDate
|
|
93
|
+
export declare const formatUntil: (target: PossibleDate, current?: PossibleDate) => string;
|
|
94
94
|
/**
|
|
95
95
|
* Return short description of when a date will happen, e.g. `10d` or `2h` or `-1w`
|
|
96
96
|
*
|
|
97
97
|
* @param target The date when the thing happened.
|
|
98
98
|
* @param current Today's date (or a different date to measure from).
|
|
99
99
|
*/
|
|
100
|
-
export declare const formatAgo: (target: PossibleDate, current?: PossibleDate
|
|
100
|
+
export declare const formatAgo: (target: PossibleDate, current?: PossibleDate) => string;
|