shelving 1.86.0 → 1.86.2
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/api/Resource.d.ts +2 -2
- package/constraint/Constraints.js +7 -6
- package/constraint/FilterConstraint.d.ts +4 -4
- package/constraint/FilterConstraint.js +17 -17
- package/constraint/QueryConstraints.d.ts +1 -1
- package/constraint/QueryConstraints.js +8 -8
- package/constraint/SortConstraint.d.ts +4 -4
- package/constraint/SortConstraint.js +3 -3
- package/db/Change.d.ts +4 -4
- package/db/Item.d.ts +4 -4
- package/error/ThroughError.js +1 -1
- package/markup/index.d.ts +1 -0
- package/markup/index.js +1 -0
- package/markup/options.d.ts +2 -2
- package/markup/regexp.d.ts +2 -2
- package/markup/render.js +19 -20
- package/markup/rule.d.ts +80 -0
- package/markup/rule.js +63 -0
- package/markup/rules.d.ts +17 -67
- package/markup/rules.js +88 -160
- package/package.json +17 -17
- package/react/useItem.js +10 -10
- package/react/useQuery.js +29 -29
- package/schema/AllowSchema.d.ts +4 -4
- package/schema/AllowSchema.js +3 -3
- package/schema/ArraySchema.d.ts +1 -1
- package/schema/BooleanSchema.d.ts +1 -1
- package/schema/DataSchema.d.ts +2 -2
- package/schema/DateSchema.d.ts +1 -1
- package/schema/DictionarySchema.d.ts +1 -1
- package/schema/LinkSchema.d.ts +1 -1
- package/schema/NumberSchema.d.ts +1 -1
- package/schema/NumberSchema.js +4 -4
- package/schema/Schema.d.ts +1 -1
- package/schema/StringSchema.d.ts +3 -3
- package/schema/ThroughSchema.d.ts +1 -1
- package/schema/TimeSchema.d.ts +1 -1
- package/state/State.d.ts +1 -1
- package/state/State.js +6 -6
- package/test/basics.d.ts +2 -2
- package/test/index.d.ts +1 -1
- package/test/people.d.ts +2 -2
- package/update/ArrayUpdate.d.ts +2 -1
- package/update/ArrayUpdate.js +9 -8
- package/update/DataUpdate.d.ts +1 -1
- package/update/DataUpdate.js +7 -6
- package/update/DictionaryUpdate.d.ts +1 -1
- package/update/DictionaryUpdate.js +8 -7
- package/util/array.d.ts +4 -4
- package/util/async.js +8 -8
- package/util/class.d.ts +3 -3
- package/util/clone.js +4 -3
- package/util/color.d.ts +2 -2
- package/util/color.js +6 -6
- package/util/data.d.ts +7 -14
- package/util/data.js +1 -19
- package/util/date.d.ts +3 -3
- package/util/debug.d.ts +1 -0
- package/util/debug.js +5 -5
- package/util/dictionary.d.ts +5 -5
- package/util/duration.d.ts +17 -0
- package/util/duration.js +52 -0
- package/util/entry.d.ts +3 -3
- package/util/equal.js +6 -3
- package/util/function.d.ts +8 -8
- package/util/hydrate.d.ts +3 -3
- package/util/hydrate.js +2 -2
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/util/iterate.d.ts +1 -1
- package/util/jsx.d.ts +3 -3
- package/util/lazy.d.ts +1 -1
- package/util/map.d.ts +15 -19
- package/util/map.js +11 -13
- package/util/match.d.ts +2 -2
- package/util/merge.d.ts +1 -1
- package/util/null.d.ts +1 -1
- package/util/number.d.ts +4 -2
- package/util/number.js +8 -6
- package/util/object.d.ts +24 -11
- package/util/object.js +30 -4
- package/util/regexp.d.ts +2 -3
- package/util/serialise.js +2 -2
- package/util/set.d.ts +4 -4
- package/util/sort.d.ts +2 -2
- package/util/source.js +2 -2
- package/util/string.d.ts +1 -1
- package/util/string.js +3 -3
- package/util/template.d.ts +2 -2
- package/util/template.js +9 -9
- package/util/time.d.ts +2 -2
- package/util/time.js +3 -3
- package/util/transform.d.ts +5 -5
- package/util/units.d.ts +39 -50
- package/util/units.js +36 -74
- package/util/url.d.ts +2 -2
- package/util/validate.d.ts +5 -5
package/util/object.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import type { ImmutableArray } from "./array.js";
|
|
2
2
|
/** Any readonly objet. */
|
|
3
|
-
export
|
|
3
|
+
export type ImmutableObject<K extends PropertyKey = PropertyKey, T = unknown> = {
|
|
4
4
|
readonly [KK in K]: T;
|
|
5
5
|
};
|
|
6
6
|
/** Any writable object. */
|
|
7
|
-
export
|
|
7
|
+
export type MutableObject<K extends PropertyKey = PropertyKey, T = unknown> = {
|
|
8
8
|
[KK in K]: T;
|
|
9
9
|
};
|
|
10
10
|
/** Prop for an object. */
|
|
11
|
-
export
|
|
11
|
+
export type ObjectProp<T extends ImmutableObject = ImmutableObject> = readonly [keyof T, T[keyof T]];
|
|
12
12
|
/** Key for an object prop. */
|
|
13
|
-
export
|
|
13
|
+
export type ObjectKey<T extends ImmutableObject = ImmutableObject> = keyof T;
|
|
14
14
|
/** Value for an object prop. */
|
|
15
|
-
export
|
|
15
|
+
export type ObjectValue<T extends ImmutableObject = ImmutableObject> = T[keyof T];
|
|
16
16
|
/** Is an unknown value an unknown object? */
|
|
17
17
|
export declare const isObject: <T extends ImmutableObject<PropertyKey, unknown>>(value: unknown) => value is T;
|
|
18
18
|
/** Assert that a value is an object */
|
|
@@ -28,7 +28,7 @@ export declare const isProp: <T extends ImmutableObject<PropertyKey, unknown>>(o
|
|
|
28
28
|
* - See https://github.com/microsoft/TypeScript/issues/24509
|
|
29
29
|
* - Consistency with `Readonly<T>`
|
|
30
30
|
*/
|
|
31
|
-
export
|
|
31
|
+
export type Mutable<T> = {
|
|
32
32
|
-readonly [K in keyof T]: T[K];
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
@@ -36,7 +36,7 @@ export declare type Mutable<T> = {
|
|
|
36
36
|
* - Any value that extends `UnknownObject` has its props made partial.
|
|
37
37
|
* - Works deeply on nested objects too.
|
|
38
38
|
*/
|
|
39
|
-
export
|
|
39
|
+
export type DeepPartial<T> = {
|
|
40
40
|
[K in keyof T]?: DeepPartial<T[K]>;
|
|
41
41
|
};
|
|
42
42
|
/**
|
|
@@ -44,7 +44,7 @@ export declare type DeepPartial<T> = {
|
|
|
44
44
|
* - Any value that extends `UnknownObject` has its props made mutable.
|
|
45
45
|
* - Works deeply on nested objects too.
|
|
46
46
|
*/
|
|
47
|
-
export
|
|
47
|
+
export type DeepMutable<T> = {
|
|
48
48
|
-readonly [K in keyof T]: DeepMutable<T[K]>;
|
|
49
49
|
};
|
|
50
50
|
/**
|
|
@@ -52,15 +52,15 @@ export declare type DeepMutable<T> = {
|
|
|
52
52
|
* - Any value that extends `UnknownObject` has its props made readonly.
|
|
53
53
|
* - Works deeply on nested objects too.
|
|
54
54
|
*/
|
|
55
|
-
export
|
|
55
|
+
export type DeepReadonly<T> = {
|
|
56
56
|
+readonly [K in keyof T]: DeepReadonly<T[K]>;
|
|
57
57
|
};
|
|
58
58
|
/** Pick only the properties of an object that match a type. */
|
|
59
|
-
export
|
|
59
|
+
export type PickProps<T, TT> = Pick<T, {
|
|
60
60
|
[K in keyof T]: T[K] extends TT ? K : never;
|
|
61
61
|
}[keyof T]>;
|
|
62
62
|
/** Omit the properties of an object that match a type. */
|
|
63
|
-
export
|
|
63
|
+
export type OmitProps<T, TT> = Omit<T, {
|
|
64
64
|
[K in keyof T]: T[K] extends TT ? K : never;
|
|
65
65
|
}[keyof T]>;
|
|
66
66
|
/** Get the props of an object as a set of entries. */
|
|
@@ -84,6 +84,7 @@ export declare function getProp<T extends ImmutableObject, K1 extends keyof T>(o
|
|
|
84
84
|
/** Set a prop on an object (immutably) and return a new object including that prop. */
|
|
85
85
|
export declare function withProp<T extends ImmutableObject, K extends keyof T>(input: T, key: K, value: T[K]): T;
|
|
86
86
|
/** Set several props on an object (immutably) and return a new object including those props. */
|
|
87
|
+
export declare function withProps<T>(input: T, props: Partial<T>): T;
|
|
87
88
|
export declare function withProps<T extends ImmutableObject>(input: T, props: T | Partial<T> | Iterable<ObjectProp<T>>): T;
|
|
88
89
|
/** Remove several props from an object (immutably) and return a new object without those props. */
|
|
89
90
|
export declare function omitProps<T extends ImmutableObject, K extends keyof T>(input: T, ...keys: K[]): Omit<T, K>;
|
|
@@ -95,3 +96,15 @@ export declare function setProp<T extends MutableObject, K extends keyof T>(obj:
|
|
|
95
96
|
export declare function setProps<T extends MutableObject>(obj: T, entries: T | Partial<T> | Iterable<ObjectProp<T>>): void;
|
|
96
97
|
/** Remove several key/value entries from an object (by reference). */
|
|
97
98
|
export declare function deleteProps<T extends MutableObject>(obj: T, ...keys: (keyof T)[]): void;
|
|
99
|
+
/**
|
|
100
|
+
* Format an unknown object as a string.
|
|
101
|
+
* - Use the custom `.toString()` function if it exists (don't use built in `Object.prototype.toString` because it's useless.
|
|
102
|
+
* - Use `.title` or `.name` or `.id` if they exist and are strings.
|
|
103
|
+
* - Use `Object` otherwise.
|
|
104
|
+
*/
|
|
105
|
+
export declare function formatObject(obj: ImmutableObject): string;
|
|
106
|
+
/**
|
|
107
|
+
* Get the prototype of an object instance.
|
|
108
|
+
* - Recommend to use this because Typescript's default lib specifies `Object.getPrototypeOf()` returning `any`.
|
|
109
|
+
*/
|
|
110
|
+
export declare function getPrototype<T>(obj: T): Partial<T> | null;
|
package/util/object.js
CHANGED
|
@@ -10,7 +10,7 @@ export function assertObject(value) {
|
|
|
10
10
|
/** is an unknown value an unknown plain object? */
|
|
11
11
|
export function isPlainObject(value) {
|
|
12
12
|
if (isObject(value)) {
|
|
13
|
-
const proto =
|
|
13
|
+
const proto = getPrototype(value);
|
|
14
14
|
return proto === null || proto === Object.prototype;
|
|
15
15
|
}
|
|
16
16
|
return false;
|
|
@@ -30,13 +30,12 @@ export function getProp(data, k1, k2, k3, k4) {
|
|
|
30
30
|
}
|
|
31
31
|
/** Set a prop on an object (immutably) and return a new object including that prop. */
|
|
32
32
|
export function withProp(input, key, value) {
|
|
33
|
-
return input[key] === value ? input : { ...input, [key]: value };
|
|
33
|
+
return input[key] === value ? input : { __proto__: getPrototype(input), ...input, [key]: value };
|
|
34
34
|
}
|
|
35
|
-
/** Set several props on an object (immutably) and return a new object including those props. */
|
|
36
35
|
export function withProps(input, props) {
|
|
37
36
|
for (const [k, v] of getProps(props))
|
|
38
37
|
if (input[k] !== v)
|
|
39
|
-
return { ...input, ...props };
|
|
38
|
+
return { __proto__: getPrototype(input), ...input, ...props };
|
|
40
39
|
return input;
|
|
41
40
|
}
|
|
42
41
|
export function omitProps(input, ...keys) {
|
|
@@ -69,3 +68,30 @@ export function deleteProps(obj, ...keys) {
|
|
|
69
68
|
for (const key of keys)
|
|
70
69
|
delete obj[key];
|
|
71
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Format an unknown object as a string.
|
|
73
|
+
* - Use the custom `.toString()` function if it exists (don't use built in `Object.prototype.toString` because it's useless.
|
|
74
|
+
* - Use `.title` or `.name` or `.id` if they exist and are strings.
|
|
75
|
+
* - Use `Object` otherwise.
|
|
76
|
+
*/
|
|
77
|
+
export function formatObject(obj) {
|
|
78
|
+
if (typeof obj.toString === "function" && obj.toString !== Object.prototype.toString)
|
|
79
|
+
return obj.toString();
|
|
80
|
+
const name = obj.name;
|
|
81
|
+
if (typeof name === "string")
|
|
82
|
+
return name;
|
|
83
|
+
const title = obj.title;
|
|
84
|
+
if (typeof title === "string")
|
|
85
|
+
return title;
|
|
86
|
+
const id = obj.id;
|
|
87
|
+
if (typeof id === "string")
|
|
88
|
+
return id;
|
|
89
|
+
return "Object";
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get the prototype of an object instance.
|
|
93
|
+
* - Recommend to use this because Typescript's default lib specifies `Object.getPrototypeOf()` returning `any`.
|
|
94
|
+
*/
|
|
95
|
+
export function getPrototype(obj) {
|
|
96
|
+
return Object.getPrototypeOf(obj);
|
|
97
|
+
}
|
package/util/regexp.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const ALWAYS_REGEXP: RegExp;
|
|
|
5
5
|
/** Regular expression that never matches anything. */
|
|
6
6
|
export declare const NEVER_REGEXP: RegExp;
|
|
7
7
|
/** Things that can be convert to a regular expression. */
|
|
8
|
-
export
|
|
8
|
+
export type PossibleRegExp = string | RegExp;
|
|
9
9
|
/** Is an unknown value a `RegExp` instance? */
|
|
10
10
|
export declare const isRegExp: <T extends RegExp>(v: unknown) => v is T;
|
|
11
11
|
/** Assert that an unknown value is a `RegExp` instance. */
|
|
@@ -17,12 +17,11 @@ export declare const getRegExpSource: (regexp: PossibleRegExp) => string;
|
|
|
17
17
|
/** Escape special characters in a string regular expression. */
|
|
18
18
|
export declare const escapeRegExp: (pattern: string) => string;
|
|
19
19
|
/** Set of named match groups from a regular expression. */
|
|
20
|
-
export
|
|
20
|
+
export type NamedRegExpData = {
|
|
21
21
|
[named: string]: string;
|
|
22
22
|
};
|
|
23
23
|
/** Regular expression match array that you've asserted contains the specified named groups. */
|
|
24
24
|
export interface NamedRegExpArray<T extends NamedRegExpData = NamedRegExpData> extends RegExpExecArray {
|
|
25
|
-
0: string;
|
|
26
25
|
groups: T;
|
|
27
26
|
}
|
|
28
27
|
/** Regular expression that you've asserted contains the specified named capture groups. */
|
package/util/serialise.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AssertionError } from "../error/AssertionError.js";
|
|
2
2
|
import { isArray } from "./array.js";
|
|
3
|
-
import { isObject } from "./object.js";
|
|
3
|
+
import { getPrototype, isObject } from "./object.js";
|
|
4
4
|
const R_QUOTE = /"/g;
|
|
5
5
|
/**
|
|
6
6
|
* Custom JSON.stringify()
|
|
@@ -31,7 +31,7 @@ export function serialise(value) {
|
|
|
31
31
|
if (isArray(value))
|
|
32
32
|
return `[${value.map(serialise).join(",")}]`;
|
|
33
33
|
if (isObject(value)) {
|
|
34
|
-
const prototype =
|
|
34
|
+
const prototype = getPrototype(value);
|
|
35
35
|
const type = prototype !== Object.prototype && prototype !== null ? (_a = prototype === null || prototype === void 0 ? void 0 : prototype.constructor) === null || _a === void 0 ? void 0 : _a.name : undefined;
|
|
36
36
|
// Use custom `toString()` function if it's defined.
|
|
37
37
|
if (type && value.toString !== Object.prototype.toString)
|
package/util/set.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/** `Set` that cannot be changed. */
|
|
2
|
-
export
|
|
2
|
+
export type ImmutableSet<T = unknown> = ReadonlySet<T>;
|
|
3
3
|
/** `Set` that can be changed. */
|
|
4
|
-
export
|
|
4
|
+
export type MutableSet<T = unknown> = Set<T>;
|
|
5
5
|
/** Things that can be converted to sets. */
|
|
6
|
-
export
|
|
6
|
+
export type PossibleSet<T> = ImmutableSet<T> | Iterable<T>;
|
|
7
7
|
/** Get the type of the _items_ in a set. */
|
|
8
|
-
export
|
|
8
|
+
export type SetItem<X> = X extends ReadonlySet<infer Y> ? Y : never;
|
|
9
9
|
/** Is an unknown value a set? */
|
|
10
10
|
export declare const isSet: <T extends ImmutableSet<unknown>>(v: unknown) => v is T;
|
|
11
11
|
/** Is an unknown value an item in a set? */
|
package/util/sort.d.ts
CHANGED
|
@@ -4,9 +4,9 @@ export interface Rankable<T> {
|
|
|
4
4
|
rank(left: T, right: T): number;
|
|
5
5
|
}
|
|
6
6
|
/** Function that can rank two values. */
|
|
7
|
-
export
|
|
7
|
+
export type Rank<T> = (left: T, right: T) => number;
|
|
8
8
|
/** Something that can rank two values. */
|
|
9
|
-
export
|
|
9
|
+
export type Ranker<T> = Rankable<T> | Rank<T>;
|
|
10
10
|
/** Rank two values with a `Ranker`. */
|
|
11
11
|
export declare function rank<T>(left: T, ranker: Ranker<T>, right: T): number;
|
|
12
12
|
/**
|
package/util/source.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AssertionError } from "../error/AssertionError.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isObject } from "./object.js";
|
|
3
3
|
/**
|
|
4
4
|
* Recurse through `Sourceable` objects and return the first one that is an instance of `type`, or `null` if no source object matches.
|
|
5
5
|
*/
|
|
6
6
|
export function getOptionalSource(type, value) {
|
|
7
|
-
if (
|
|
7
|
+
if (isObject(value)) {
|
|
8
8
|
if (value instanceof type)
|
|
9
9
|
return value;
|
|
10
10
|
if ("source" in value)
|
package/util/string.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { ImmutableArray } from "./array.js";
|
|
|
5
5
|
* - Using `Iterable<string> & NotString` allows an iterable containing strings but not `string` itself.
|
|
6
6
|
* - This helps catch this category of subtle errors.
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
8
|
+
export type NotString = {
|
|
9
9
|
toUpperCase?: never;
|
|
10
10
|
toLowerCase?: never;
|
|
11
11
|
};
|
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 {
|
|
4
|
+
import { formatObject, isObject } from "./object.js";
|
|
5
5
|
import { getArray, isArray } from "./array.js";
|
|
6
6
|
import { formatNumber, isBetween } from "./number.js";
|
|
7
7
|
/** Is a value a string? */
|
|
@@ -41,8 +41,8 @@ export function getString(value) {
|
|
|
41
41
|
return formatDate(value);
|
|
42
42
|
if (isArray(value))
|
|
43
43
|
return value.map(getString).join(", ");
|
|
44
|
-
if (
|
|
45
|
-
return
|
|
44
|
+
if (isObject(value))
|
|
45
|
+
return formatObject(value);
|
|
46
46
|
return "Unknown";
|
|
47
47
|
}
|
|
48
48
|
/** Concatenate an iterable set of strings together. */
|
package/util/template.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { NotString } from "./string.js";
|
|
2
2
|
import type { ImmutableDictionary } from "./dictionary.js";
|
|
3
3
|
/** Template values in `{ placeholder: value }` format. */
|
|
4
|
-
|
|
4
|
+
type TemplateValues = ImmutableDictionary<string>;
|
|
5
5
|
/** Things that can be converted to the value for a named placeholder. */
|
|
6
|
-
|
|
6
|
+
type PlaceholderValues = string | ((name: string) => string) | string[] | TemplateValues;
|
|
7
7
|
/**
|
|
8
8
|
* Get list of placeholders named in a template string.
|
|
9
9
|
*
|
package/util/template.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { isObject } from "./object.js";
|
|
2
|
+
import { setMapItem } from "./map.js";
|
|
3
|
+
import { EMPTY_DATA } from "./data.js";
|
|
2
4
|
// RegExp to find named variables in several formats e.g. `:a`, `${b}`, `{{c}}` or `{d}`
|
|
3
5
|
const R_PLACEHOLDERS = /(\*|:[a-z][a-z0-9]*|\$\{[a-z][a-z0-9]*\}|\{\{[a-z][a-z0-9]*\}\}|\{[a-z][a-z0-9]*\})/i;
|
|
4
6
|
// Find actual name within template placeholder e.g. `${name}` → `name`
|
|
5
7
|
const R_NAME = /[a-z0-9]+/i;
|
|
6
|
-
// Empty template.
|
|
7
|
-
const EMPTY_TEMPLATE = Object.create(null);
|
|
8
8
|
// Cache of templates.
|
|
9
|
-
const TEMPLATE_CACHE =
|
|
9
|
+
const TEMPLATE_CACHE = new Map();
|
|
10
10
|
/**
|
|
11
11
|
* Split up a template into an array of separator → placeholder → separator → placeholder → separator
|
|
12
12
|
* - Odd numbered chunks are separators.
|
|
@@ -15,7 +15,7 @@ const TEMPLATE_CACHE = Object.create(null);
|
|
|
15
15
|
* @param template The template including template placeholders, e.g. `:name-${country}/{city}`
|
|
16
16
|
* @returns Array of strings alternating separator and placeholder.
|
|
17
17
|
*/
|
|
18
|
-
const
|
|
18
|
+
const _splitTemplate = (template) => TEMPLATE_CACHE.get(template) || setMapItem(TEMPLATE_CACHE, template, _split(template));
|
|
19
19
|
const _split = (template) => {
|
|
20
20
|
var _a;
|
|
21
21
|
const matches = template.split(R_PLACEHOLDERS);
|
|
@@ -38,7 +38,7 @@ const _split = (template) => {
|
|
|
38
38
|
* @param template The template including template placeholders, e.g. `:name-${country}/{city}`
|
|
39
39
|
* @returns Array of clean string names of found placeholders, e.g. `["name", "country", "city"]`
|
|
40
40
|
*/
|
|
41
|
-
export const getPlaceholders = (template) =>
|
|
41
|
+
export const getPlaceholders = (template) => _splitTemplate(template).map(_getPlaceholder);
|
|
42
42
|
const _getPlaceholder = ({ name }) => name;
|
|
43
43
|
/**
|
|
44
44
|
* Match a template against a target string.
|
|
@@ -51,17 +51,17 @@ const _getPlaceholder = ({ name }) => name;
|
|
|
51
51
|
*/
|
|
52
52
|
export function matchTemplate(template, target) {
|
|
53
53
|
// Get separators and placeholders from template.
|
|
54
|
-
const chunks =
|
|
54
|
+
const chunks = _splitTemplate(template);
|
|
55
55
|
const firstChunk = chunks[0];
|
|
56
56
|
// Return early if empty.
|
|
57
57
|
if (!firstChunk)
|
|
58
|
-
return template === target ?
|
|
58
|
+
return template === target ? EMPTY_DATA : undefined;
|
|
59
59
|
// Check first separator.
|
|
60
60
|
if (!target.startsWith(firstChunk.pre))
|
|
61
61
|
return undefined; // target doesn't match template
|
|
62
62
|
// Loop through the placeholders (placeholders are at all the even-numbered positions in `chunks`).
|
|
63
63
|
let startIndex = firstChunk.pre.length;
|
|
64
|
-
const values =
|
|
64
|
+
const values = {};
|
|
65
65
|
for (const { name, post } of chunks) {
|
|
66
66
|
const stopIndex = !post ? Infinity : target.indexOf(post, startIndex);
|
|
67
67
|
if (stopIndex < 0)
|
|
@@ -96,7 +96,7 @@ export function matchTemplates(templates, target) {
|
|
|
96
96
|
* @throws {ReferenceError} If a placeholder in the template string is not specified in values.
|
|
97
97
|
*/
|
|
98
98
|
export const renderTemplate = (template, value) => {
|
|
99
|
-
const chunks =
|
|
99
|
+
const chunks = _splitTemplate(template);
|
|
100
100
|
if (!chunks.length)
|
|
101
101
|
return template;
|
|
102
102
|
let output = template;
|
package/util/time.d.ts
CHANGED
|
@@ -33,9 +33,9 @@ export declare class Time {
|
|
|
33
33
|
/** Regular expression that matches a time in ISO 8601 format. */
|
|
34
34
|
export declare const TIME_REGEXP: RegExp;
|
|
35
35
|
/** Things that converted to times. */
|
|
36
|
-
export
|
|
36
|
+
export type PossibleTime = Time | Date | number | string;
|
|
37
37
|
/** Things that converted to times or `null` */
|
|
38
|
-
export
|
|
38
|
+
export type PossibleOptionalTime = Time | Date | number | string | null;
|
|
39
39
|
/** Is an unknown value a `Time` instance. */
|
|
40
40
|
export declare const isTime: (v: Time | unknown) => v is Time;
|
|
41
41
|
/**
|
package/util/time.js
CHANGED
|
@@ -4,9 +4,6 @@ import { getOptionalDate } from "./date.js";
|
|
|
4
4
|
import { wrapNumber } from "./number.js";
|
|
5
5
|
/** Class representing a time in the day in 24 hour format in the user's current locale. */
|
|
6
6
|
export class Time {
|
|
7
|
-
constructor(time) {
|
|
8
|
-
this.time = wrapNumber(Math.round(time), 0, DAY);
|
|
9
|
-
}
|
|
10
7
|
/** Make a new `Time` instance from a date (or any value that can be converted to a date). */
|
|
11
8
|
static fromDate(possible) {
|
|
12
9
|
const date = getOptionalDate(possible);
|
|
@@ -20,6 +17,9 @@ export class Time {
|
|
|
20
17
|
const [, h, m, s, ms] = matches;
|
|
21
18
|
return new Time(parseInt(h, 10) * HOUR + parseInt(m, 10) * MINUTE + (typeof s === "string" ? parseInt(s, 10) * SECOND : 0) + (typeof ms === "string" ? parseInt(ms, 10) : 0));
|
|
22
19
|
}
|
|
20
|
+
constructor(time) {
|
|
21
|
+
this.time = wrapNumber(Math.round(time), 0, DAY);
|
|
22
|
+
}
|
|
23
23
|
/** Get the number of hours in this time. */
|
|
24
24
|
get h() {
|
|
25
25
|
return Math.trunc(this.time / HOUR);
|
package/util/transform.d.ts
CHANGED
|
@@ -13,13 +13,13 @@ export interface AsyncTransformable<I, O> {
|
|
|
13
13
|
/** Is an unknown value a transformable. */
|
|
14
14
|
export declare const isTransformable: <T extends Transformable<unknown, unknown>>(v: unknown) => v is T;
|
|
15
15
|
/** Function that can transform an input value into an output value. */
|
|
16
|
-
export
|
|
16
|
+
export type Transform<I, O> = (input: I) => O;
|
|
17
17
|
/** Function that can transform an input value into an output value. */
|
|
18
|
-
export
|
|
18
|
+
export type AsyncTransform<I, O> = (input: I) => O | PromiseLike<O>;
|
|
19
19
|
/** Something that can transform an input value into an output value (or a plain value). */
|
|
20
|
-
export
|
|
20
|
+
export type Transformer<I, O> = Transformable<I, O> | Transform<I, O> | O;
|
|
21
21
|
/** Something that can transform an input value into an output value (or a plain value). */
|
|
22
|
-
export
|
|
22
|
+
export type AsyncTransformer<I, O> = AsyncTransformable<I, O> | AsyncTransform<I, O> | O;
|
|
23
23
|
/** Transform a value using a transformer. */
|
|
24
24
|
export declare function transform<I, O>(input: I, transformer: (v: I) => O): O;
|
|
25
25
|
export declare function transform<I, O>(input: I, transformer: (v: I) => O | PromiseLike<O>): O | PromiseLike<O>;
|
|
@@ -38,7 +38,7 @@ export declare const mapDictionary: <I, O>(dictionary: ImmutableDictionary<I>, t
|
|
|
38
38
|
/** Modify the values of a set of entries using a transformer. */
|
|
39
39
|
export declare function mapEntries<K, I, O>(entries: Iterable<Entry<K, I>>, transformer: Transformer<I, O>): Iterable<Entry<K, O>>;
|
|
40
40
|
/** Set of named transformers for a data object (or `undefined` to skip the transform). */
|
|
41
|
-
export
|
|
41
|
+
export type Transformers<T extends ImmutableObject> = {
|
|
42
42
|
readonly [K in keyof T]?: Transformer<T[K], T[K]> | undefined;
|
|
43
43
|
};
|
|
44
44
|
/** Transform an object using a set of named transformers. */
|
package/util/units.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { ImmutableObject } from "./object.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
declare type Conversion = number | ((num: number) => number);
|
|
2
|
+
import { MapKey, ImmutableMap } from "./map.js";
|
|
3
|
+
/** Conversion from one unit to another (either an amount to multiple by, or a function to convert). */
|
|
4
|
+
type Conversion = number | ((num: number) => number);
|
|
6
5
|
/** Set of possible conversions for a set of items. */
|
|
7
|
-
|
|
6
|
+
type Conversions<T extends string> = {
|
|
8
7
|
readonly [K in T]?: Conversion;
|
|
9
8
|
};
|
|
10
|
-
|
|
9
|
+
type UnitProps<T extends string> = {
|
|
11
10
|
/** Short abbreviation for this unit, e.g. `km` (defaults to first letter of `id`). */
|
|
12
11
|
readonly abbr?: string;
|
|
13
12
|
/** Singular name for this unit, e.g. `kilometer` (defaults to `id` + "s"). */
|
|
@@ -20,12 +19,12 @@ declare type UnitProps<T extends string> = {
|
|
|
20
19
|
readonly to?: Conversions<T>;
|
|
21
20
|
};
|
|
22
21
|
/** Represent a unit. */
|
|
23
|
-
export declare class Unit<
|
|
22
|
+
export declare class Unit<K extends string> {
|
|
24
23
|
/** `UnitList` this unit belongs to. */
|
|
25
|
-
readonly list: UnitList<
|
|
24
|
+
readonly list: UnitList<K>;
|
|
26
25
|
private readonly _to;
|
|
27
|
-
/**
|
|
28
|
-
readonly
|
|
26
|
+
/** String key for this unit, e.g. `kilometer` */
|
|
27
|
+
readonly key: K;
|
|
29
28
|
/** Short abbreviation for this unit, e.g. `km` (defaults to first letter of `id`). */
|
|
30
29
|
readonly abbr: string;
|
|
31
30
|
/** Singular name for this unit, e.g. `kilometer` (defaults to `id`). */
|
|
@@ -38,73 +37,63 @@ export declare class Unit<T extends string> {
|
|
|
38
37
|
get title(): string;
|
|
39
38
|
constructor(
|
|
40
39
|
/** `UnitList` this unit belongs to. */
|
|
41
|
-
list: UnitList<
|
|
42
|
-
/**
|
|
43
|
-
|
|
40
|
+
list: UnitList<K>,
|
|
41
|
+
/** String key for this unit, e.g. `kilometer` */
|
|
42
|
+
key: K,
|
|
44
43
|
/** Props to configure this unit. */
|
|
45
|
-
{ abbr, singular, plural, precision, to }: UnitProps<
|
|
44
|
+
{ abbr, singular, plural, precision, to }: UnitProps<K>);
|
|
46
45
|
/** Convert an amount from this unit to another unit. */
|
|
47
|
-
to(amount: number,
|
|
46
|
+
to(amount: number, unit?: K | Unit<K>): number;
|
|
48
47
|
/** Convert an amount from another unit to this unit. */
|
|
49
|
-
from(amount: number,
|
|
48
|
+
from(amount: number, unit?: K | Unit<K>): number;
|
|
50
49
|
/** Convert an amount from this unit to another unit (must specify another `Unit` instance). */
|
|
51
50
|
private _toUnit;
|
|
52
|
-
/** Format
|
|
51
|
+
/** Format an amount with a given unit of measure, e.g. `12 kg` or `29.5 l` */
|
|
53
52
|
format(amount: number, precision?: number | null): string;
|
|
54
|
-
/** Format
|
|
53
|
+
/** Format an amount with a given unit of measure, e.g. `12 kilograms` or `29.5 liters` or `1 degree` */
|
|
55
54
|
formatFull(amount: number, precision?: number | null): string;
|
|
55
|
+
/** Cram an amount with a given unit of measure, e.g. `1.25M mi` */
|
|
56
|
+
cram(amount: number): string;
|
|
56
57
|
}
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Represent a list of units.
|
|
60
|
+
* - Has a known base unit at `.base`
|
|
61
|
+
* - Cannot have additional units added after it is created.
|
|
62
|
+
*/
|
|
63
|
+
export declare class UnitList<K extends string> extends ImmutableMap<K, Unit<K>> {
|
|
64
|
+
readonly base: Unit<K>;
|
|
65
|
+
constructor(units: ImmutableObject<K, UnitProps<K>>);
|
|
66
|
+
/** Convert an amount from a unit to another unit. */
|
|
67
|
+
convert(amount: number, sourceUnit: K | Unit<K>, targetUnit: K | Unit<K>): number;
|
|
61
68
|
}
|
|
62
69
|
/** Percentage units. */
|
|
63
70
|
export declare const PERCENTAGE_UNITS: UnitList<"percent">;
|
|
64
|
-
export
|
|
71
|
+
export type PercentageUnitKey = MapKey<typeof PERCENTAGE_UNITS>;
|
|
65
72
|
/** Point units. */
|
|
66
73
|
export declare const POINT_UNITS: UnitList<"basis-point" | "percentage-point">;
|
|
67
|
-
export
|
|
74
|
+
export type PointUnitKey = MapKey<typeof POINT_UNITS>;
|
|
68
75
|
/** Angle units. */
|
|
69
76
|
export declare const ANGLE_UNITS: UnitList<"degree" | "radian" | "gradian">;
|
|
70
|
-
export
|
|
77
|
+
export type AngleUnitKey = MapKey<typeof ANGLE_UNITS>;
|
|
71
78
|
/** Mass units. */
|
|
72
79
|
export declare const MASS_UNITS: UnitList<"milligram" | "gram" | "kilogram" | "ounce" | "pound" | "stone">;
|
|
73
|
-
export
|
|
80
|
+
export type MassUnitKey = MapKey<typeof MASS_UNITS>;
|
|
74
81
|
/** Time units. */
|
|
75
82
|
export declare const TIME_UNITS: UnitList<"millisecond" | "second" | "minute" | "hour" | "day" | "week" | "month" | "year">;
|
|
76
|
-
export
|
|
83
|
+
export type TimeUnitKey = MapKey<typeof TIME_UNITS>;
|
|
77
84
|
/** Length units. */
|
|
78
85
|
export declare const LENGTH_UNITS: UnitList<"millimeter" | "centimeter" | "meter" | "kilometer" | "inch" | "foot" | "yard" | "furlong" | "mile">;
|
|
79
|
-
export
|
|
86
|
+
export type LengthUnitKey = MapKey<typeof LENGTH_UNITS>;
|
|
80
87
|
/** Speed units. */
|
|
81
88
|
export declare const SPEED_UNITS: UnitList<"meter-per-second" | "kilometer-per-hour" | "mile-per-hour">;
|
|
82
|
-
export
|
|
89
|
+
export type SpeedUnitKey = MapKey<typeof SPEED_UNITS>;
|
|
83
90
|
/** Area units. */
|
|
84
91
|
export declare const AREA_UNITS: UnitList<"square-millimeter" | "square-centimeter" | "square-meter" | "square-kilometer" | "hectare" | "square-inch" | "square-foot" | "square-yard" | "acre">;
|
|
85
|
-
export
|
|
92
|
+
export type AreaUnitKey = MapKey<typeof AREA_UNITS>;
|
|
86
93
|
/** Volume units. */
|
|
87
94
|
export declare const VOLUME_UNITS: UnitList<"milliliter" | "liter" | "cubic-centimeter" | "cubic-meter" | "us-fluid-ounce" | "us-pint" | "us-quart" | "us-gallon" | "imperial-fluid-ounce" | "imperial-pint" | "imperial-quart" | "imperial-gallon" | "cubic-inch" | "cubic-foot" | "cubic-yard">;
|
|
88
|
-
export
|
|
95
|
+
export type VolumeUnitKey = MapKey<typeof VOLUME_UNITS>;
|
|
89
96
|
/** Temperature units. */
|
|
90
97
|
export declare const TEMPERATURE_UNITS: UnitList<"celsius" | "fahrenheit" | "kelvin">;
|
|
91
|
-
export
|
|
92
|
-
/** Format a percentage (combines `getPercent()` and `formatUnits()` for convenience). */
|
|
93
|
-
export declare const formatPercent: (numerator: number, denumerator: number, precision?: number) => string;
|
|
94
|
-
/** Format a full format of a duration of time using the most reasonable units e.g. `5 years` or `1 week` or `4 minutes` or `12 milliseconds`. */
|
|
95
|
-
export declare function formatFullDuration(ms: number, precision?: number): string;
|
|
96
|
-
/** Format a description of a duration of time using the most reasonable units e.g. `5y` or `4m` or `12ms`. */
|
|
97
|
-
export declare function formatDuration(ms: number, precision?: number): string;
|
|
98
|
-
/** Full when a date happens/happened, e.g. `in 10 days` or `2 hours ago` */
|
|
99
|
-
export declare const formatFullWhen: (target: PossibleDate, current?: PossibleDate) => string;
|
|
100
|
-
/** Compact when a date happens/happened, e.g. `in 10d` or `2h ago` or `in 1w` */
|
|
101
|
-
export declare const formatWhen: (target: PossibleDate, current?: PossibleDate) => string;
|
|
102
|
-
/** Full when a date happens, e.g. `10 days` or `2 hours` or `-1 week` */
|
|
103
|
-
export declare const formatFullUntil: (target: PossibleDate, current?: PossibleDate) => string;
|
|
104
|
-
/** Compact when a date happens, e.g. `10d` or `2h` or `-1w` */
|
|
105
|
-
export declare const formatUntil: (target: PossibleDate, current?: PossibleDate) => string;
|
|
106
|
-
/** Full when a date happened, e.g. `10 days` or `2 hours` or `-1 week` */
|
|
107
|
-
export declare const formatFullAgo: (target: PossibleDate, current?: PossibleDate) => string;
|
|
108
|
-
/** Compact when a date will happen, e.g. `10d` or `2h` or `-1w` */
|
|
109
|
-
export declare const formatAgo: (target: PossibleDate, current?: PossibleDate) => string;
|
|
98
|
+
export type TemperatureUnitKey = MapKey<typeof TEMPERATURE_UNITS>;
|
|
110
99
|
export {};
|