shelving 1.117.0 → 1.117.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/error/EnhancedError.d.ts +1 -1
- package/error/EnhancedError.js +1 -1
- package/error/{AssertionError.d.ts → StateError.d.ts} +2 -2
- package/error/{AssertionError.js → StateError.js} +3 -3
- package/error/index.d.ts +1 -1
- package/error/index.js +1 -1
- package/iterate/InspectGenerator.js +4 -4
- package/package.json +1 -1
- package/react/createCacheContext.js +2 -2
- package/sequence/InspectSequence.js +4 -4
- package/util/array.js +4 -4
- package/util/assert.js +3 -3
- package/util/async.js +4 -4
- package/util/class.js +2 -2
- package/util/color.js +1 -1
- package/util/data.js +3 -3
- package/util/date.js +1 -1
- package/util/dictionary.js +1 -2
- package/util/hydrate.js +3 -3
- package/util/map.js +3 -3
- package/util/null.js +5 -5
- package/util/object.js +4 -4
- package/util/path.js +2 -2
- package/util/serialise.js +2 -2
- package/util/set.js +3 -3
- package/util/source.js +2 -2
- package/util/string.d.ts +3 -3
- package/util/string.js +6 -7
- package/util/template.js +2 -1
- package/util/time.js +1 -1
- package/util/units.js +2 -2
package/error/EnhancedError.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* - Context is appended to `.message` in the format `message: debuggedContext`
|
|
4
4
|
* - Context is converted to a string using `debug()`
|
|
5
5
|
*/
|
|
6
|
-
export declare class EnhancedError extends
|
|
6
|
+
export declare class EnhancedError extends Error {
|
|
7
7
|
readonly context: unknown;
|
|
8
8
|
constructor(message: string, context?: unknown);
|
|
9
9
|
}
|
package/error/EnhancedError.js
CHANGED
|
@@ -4,7 +4,7 @@ import { debug } from "../util/debug.js";
|
|
|
4
4
|
* - Context is appended to `.message` in the format `message: debuggedContext`
|
|
5
5
|
* - Context is converted to a string using `debug()`
|
|
6
6
|
*/
|
|
7
|
-
export class EnhancedError extends
|
|
7
|
+
export class EnhancedError extends Error {
|
|
8
8
|
context;
|
|
9
9
|
constructor(message, context) {
|
|
10
10
|
const debugged = context !== undefined ? debug(context, 2) : "";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ErrorCode } from "../util/error.js";
|
|
2
2
|
import { EnhancedError } from "./EnhancedError.js";
|
|
3
|
-
/** Thrown if the is
|
|
4
|
-
export declare class
|
|
3
|
+
/** Thrown if the state of the program is correct to execute a given operation. */
|
|
4
|
+
export declare class StateError extends EnhancedError {
|
|
5
5
|
readonly code: ErrorCode;
|
|
6
6
|
constructor(message?: string, context?: unknown);
|
|
7
7
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { EnhancedError } from "./EnhancedError.js";
|
|
2
|
-
/** Thrown if the is
|
|
3
|
-
export class
|
|
2
|
+
/** Thrown if the state of the program is correct to execute a given operation. */
|
|
3
|
+
export class StateError extends EnhancedError {
|
|
4
4
|
code = "failed-precondition";
|
|
5
5
|
constructor(message = "Failed precondition", context) {
|
|
6
6
|
super(message, context);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
StateError.prototype.name = "StateError";
|
package/error/index.d.ts
CHANGED
package/error/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StateError } from "../error/StateError.js";
|
|
2
2
|
import { ThroughGenerator } from "./ThroughGenerator.js";
|
|
3
3
|
/** Used when the sequence hasn't inspected anything yet. */
|
|
4
4
|
const _NOVALUE = Symbol("shelving/InspectGenerator.NOVALUE");
|
|
@@ -20,21 +20,21 @@ export class InspectGenerator extends ThroughGenerator {
|
|
|
20
20
|
/** The first yielded value (throws if the iteration yielded no values, i.e. `this.count === 0`). */
|
|
21
21
|
get first() {
|
|
22
22
|
if (this._first === _NOVALUE)
|
|
23
|
-
throw new
|
|
23
|
+
throw new StateError("Iteration not started");
|
|
24
24
|
return this._first;
|
|
25
25
|
}
|
|
26
26
|
_first = _NOVALUE;
|
|
27
27
|
/** The last yielded value (throws if the iteration yielded no values, i.e. `this.count === 0`). */
|
|
28
28
|
get last() {
|
|
29
29
|
if (this._last === _NOVALUE)
|
|
30
|
-
throw new
|
|
30
|
+
throw new StateError("Iteration not started");
|
|
31
31
|
return this._last;
|
|
32
32
|
}
|
|
33
33
|
_last = _NOVALUE;
|
|
34
34
|
/** The returned value (throws if the iteration is not done, i.e. `this.done === false`). */
|
|
35
35
|
get returned() {
|
|
36
36
|
if (this._returned === _NOVALUE)
|
|
37
|
-
throw new
|
|
37
|
+
throw new StateError("Iteration not done");
|
|
38
38
|
return this._returned;
|
|
39
39
|
}
|
|
40
40
|
_returned = _NOVALUE;
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, createElement, useContext, useRef } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { StateError } from "../error/StateError.js";
|
|
3
3
|
/**
|
|
4
4
|
* Create a cache context that can be provided to React elements and allows them to call `useCache()`
|
|
5
5
|
* - Cache is a `Map` indexed by strings that can be used to store any value.
|
|
@@ -10,7 +10,7 @@ export function createCacheContext() {
|
|
|
10
10
|
useCache() {
|
|
11
11
|
const cache = useContext(context);
|
|
12
12
|
if (!cache)
|
|
13
|
-
throw new
|
|
13
|
+
throw new StateError("useCache() must be used inside <Cache>");
|
|
14
14
|
return cache;
|
|
15
15
|
},
|
|
16
16
|
CacheContext({ children }) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StateError } from "../error/StateError.js";
|
|
2
2
|
import { ThroughSequence } from "./ThroughSequence.js";
|
|
3
3
|
/** Used when the sequence hasn't inspected anything yet. */
|
|
4
4
|
const _NOVALUE = Symbol("shelving/InspectSequence.NOVALUE");
|
|
@@ -20,21 +20,21 @@ export class InspectSequence extends ThroughSequence {
|
|
|
20
20
|
/** The first yielded value (throws if the iteration yielded no values, i.e. `this.count === 0`). */
|
|
21
21
|
get first() {
|
|
22
22
|
if (this._first === _NOVALUE)
|
|
23
|
-
throw new
|
|
23
|
+
throw new StateError("Iteration not started");
|
|
24
24
|
return this._first;
|
|
25
25
|
}
|
|
26
26
|
_first = _NOVALUE;
|
|
27
27
|
/** The last yielded value (throws if the iteration yielded no values, i.e. `this.count === 0`). */
|
|
28
28
|
get last() {
|
|
29
29
|
if (this._last === _NOVALUE)
|
|
30
|
-
throw new
|
|
30
|
+
throw new StateError("Iteration not started");
|
|
31
31
|
return this._last;
|
|
32
32
|
}
|
|
33
33
|
_last = _NOVALUE;
|
|
34
34
|
/** The returned value (throws if the iteration is not done, i.e. `this.done === false`). */
|
|
35
35
|
get returned() {
|
|
36
36
|
if (this._returned === _NOVALUE)
|
|
37
|
-
throw new
|
|
37
|
+
throw new StateError("Iteration not done");
|
|
38
38
|
return this._returned;
|
|
39
39
|
}
|
|
40
40
|
_returned = _NOVALUE;
|
package/util/array.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AssertionError } from "../error/AssertionError.js";
|
|
2
1
|
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
+
import { ValueError } from "../error/ValueError.js";
|
|
3
3
|
import { omitItems, pickItems } from "./iterate.js";
|
|
4
4
|
import { formatRange } from "./number.js";
|
|
5
5
|
/** Is an unknown value an array? */
|
|
@@ -7,14 +7,14 @@ export const isArray = (value) => Array.isArray(value);
|
|
|
7
7
|
/** Assert that an unknown value is an array. */
|
|
8
8
|
export function assertArray(arr) {
|
|
9
9
|
if (!isArray(arr))
|
|
10
|
-
throw new
|
|
10
|
+
throw new ValueError(`Must be array`, arr);
|
|
11
11
|
}
|
|
12
12
|
/** Is an unknown value an item in a specified array? */
|
|
13
13
|
export const isArrayItem = (arr, item) => arr.includes(item);
|
|
14
14
|
/** Assert that an unknown value is an item in a specified array. */
|
|
15
15
|
export function assertArrayItem(arr, item) {
|
|
16
16
|
if (!isArrayItem(arr, item))
|
|
17
|
-
throw new
|
|
17
|
+
throw new ValueError(`Must be array item`, item);
|
|
18
18
|
}
|
|
19
19
|
/** Convert an iterable to an array (if its not already an array). */
|
|
20
20
|
export function getArray(items) {
|
|
@@ -141,7 +141,7 @@ export function isArrayLength(arr, min = 1, max = Infinity) {
|
|
|
141
141
|
}
|
|
142
142
|
export function assertArrayLength(arr, min = 1, max = Infinity) {
|
|
143
143
|
if (!isArray(arr) || !isArrayLength(arr, min, max))
|
|
144
|
-
throw new
|
|
144
|
+
throw new ValueError(`Must be array with length ${formatRange(min, max)}`, arr);
|
|
145
145
|
}
|
|
146
146
|
export function getArrayLength(arr, min = 1, max = Infinity) {
|
|
147
147
|
assertArrayLength(arr, min, max);
|
package/util/assert.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
/** Assert two values are equal. */
|
|
3
3
|
export function assertEqual(left, right) {
|
|
4
4
|
if (left !== right)
|
|
5
|
-
throw new
|
|
5
|
+
throw new ValueError(`Must be equal`, { left, right });
|
|
6
6
|
}
|
|
7
7
|
/** Assert two values are equal. */
|
|
8
8
|
export function assertNot(left, right) {
|
|
9
9
|
if (left === right)
|
|
10
|
-
throw new
|
|
10
|
+
throw new ValueError(`Must not be equal`, { left, right });
|
|
11
11
|
}
|
package/util/async.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
/** Is a value an asynchronous value implementing a `then()` function. */
|
|
3
3
|
export const isAsync = (value) => typeof value === "object" && value !== null && typeof value.then === "function";
|
|
4
4
|
/** Is a value a synchronous value. */
|
|
@@ -16,17 +16,17 @@ export function throwAsync(value) {
|
|
|
16
16
|
/** Assert a synchronous value. */
|
|
17
17
|
export function assertNotAsync(value) {
|
|
18
18
|
if (isAsync(value))
|
|
19
|
-
throw new
|
|
19
|
+
throw new ValueError("Must be synchronous", value);
|
|
20
20
|
}
|
|
21
21
|
/** Assert an asynchronous value. */
|
|
22
22
|
export function assertAsync(value) {
|
|
23
23
|
if (!isAsync(value))
|
|
24
|
-
throw new
|
|
24
|
+
throw new ValueError("Must be asynchronous", value);
|
|
25
25
|
}
|
|
26
26
|
/** Assert a promise. */
|
|
27
27
|
export function assertPromise(value) {
|
|
28
28
|
if (!(value instanceof Promise))
|
|
29
|
-
throw new
|
|
29
|
+
throw new ValueError("Must be promise", value);
|
|
30
30
|
}
|
|
31
31
|
/** Run any queued microtasks now. */
|
|
32
32
|
export function runMicrotasks() {
|
package/util/class.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
import { debug } from "./debug.js";
|
|
3
3
|
/** Is a given value a class constructor? */
|
|
4
4
|
export const isConstructor = (value) => typeof value === "function" && value.toString().startsWith("class");
|
|
@@ -7,5 +7,5 @@ export const isInstance = (value, type) => value instanceof type;
|
|
|
7
7
|
/** Assert that a value is an instance of something. */
|
|
8
8
|
export function assertInstance(value, type) {
|
|
9
9
|
if (!(value instanceof type))
|
|
10
|
-
throw new
|
|
10
|
+
throw new ValueError(`Must be instance of ${debug(type)}`, value);
|
|
11
11
|
}
|
package/util/color.js
CHANGED
|
@@ -65,7 +65,7 @@ export const isColor = (value) => value instanceof Color;
|
|
|
65
65
|
/** Assert that an unknown value is a `Color` instance. */
|
|
66
66
|
export function assertColor(value) {
|
|
67
67
|
if (!isColor(value))
|
|
68
|
-
throw new ValueError("
|
|
68
|
+
throw new ValueError("Must be color", value);
|
|
69
69
|
}
|
|
70
70
|
/** Convert a possible color to a `Color` instance or `undefined` */
|
|
71
71
|
export function getOptionalColor(possible) {
|
package/util/data.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
import { isIterable } from "./iterate.js";
|
|
3
3
|
import { isObject, isPlainObject } from "./object.js";
|
|
4
4
|
/** Is an unknown value a data object? */
|
|
@@ -6,14 +6,14 @@ export const isData = (value) => isPlainObject(value);
|
|
|
6
6
|
/** Assert that an unknown value is a data object. */
|
|
7
7
|
export function assertData(value) {
|
|
8
8
|
if (!isPlainObject(value))
|
|
9
|
-
throw new
|
|
9
|
+
throw new ValueError("Must be data", value);
|
|
10
10
|
}
|
|
11
11
|
/** Is an unknown value the key for an own prop of a data object. */
|
|
12
12
|
export const isDataProp = (data, key) => typeof key === "string" && Object.hasOwn(data, key);
|
|
13
13
|
/** Assert that an unknown value is the key for an own prop of a data object. */
|
|
14
14
|
export function assertDataProp(data, key) {
|
|
15
15
|
if (!isDataProp(data, key))
|
|
16
|
-
throw new
|
|
16
|
+
throw new ValueError("Must be data prop", key);
|
|
17
17
|
}
|
|
18
18
|
export function getData(input) {
|
|
19
19
|
return isIterable(input) ? Object.fromEntries(input) : input;
|
package/util/date.js
CHANGED
|
@@ -50,7 +50,7 @@ export function getOptionalDate(possible = "now") {
|
|
|
50
50
|
export function getDate(possible) {
|
|
51
51
|
const date = getOptionalDate(possible);
|
|
52
52
|
if (!date)
|
|
53
|
-
throw new ValueError(`
|
|
53
|
+
throw new ValueError(`Invalid date`, possible);
|
|
54
54
|
return date;
|
|
55
55
|
}
|
|
56
56
|
/** Convert an unknown value to a timestamp (milliseconds past Unix epoch), or `undefined` if it couldn't be converted. */
|
package/util/dictionary.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AssertionError } from "../error/AssertionError.js";
|
|
2
1
|
import { RequiredError } from "../error/RequiredError.js";
|
|
3
2
|
import { ValueError } from "../error/ValueError.js";
|
|
4
3
|
import { isIterable } from "./iterate.js";
|
|
@@ -22,7 +21,7 @@ export const isDictionaryItem = (obj, key) => typeof key === "string" && Object.
|
|
|
22
21
|
/** Assert that an unknown value is the key for an own prop of a dictionary. */
|
|
23
22
|
export function assertDictionaryItem(obj, key) {
|
|
24
23
|
if (!isDictionaryItem(obj, key))
|
|
25
|
-
throw new
|
|
24
|
+
throw new ValueError("Must be dictionary item", key);
|
|
26
25
|
}
|
|
27
26
|
/** Get an item in a map or throw an error if it doesn't exist. */
|
|
28
27
|
export function getDictionaryItem(obj, key) {
|
package/util/hydrate.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
import { isArray } from "./array.js";
|
|
3
3
|
import { isDate } from "./date.js";
|
|
4
4
|
import { isMap } from "./map.js";
|
|
@@ -31,7 +31,7 @@ export function hydrate(value, hydrations) {
|
|
|
31
31
|
const hydration = hydrations[$type];
|
|
32
32
|
if (hydration)
|
|
33
33
|
return { __proto__: hydration.prototype, ...mapObject($value, hydrate, hydrations) };
|
|
34
|
-
throw new
|
|
34
|
+
throw new ValueError(`Cannot hydrate "${$type}" object`, value);
|
|
35
35
|
}
|
|
36
36
|
return value;
|
|
37
37
|
}
|
|
@@ -62,7 +62,7 @@ export function dehydrate(value, hydrations) {
|
|
|
62
62
|
for (const [$type, hydration] of getProps(hydrations))
|
|
63
63
|
if (proto === hydration.prototype)
|
|
64
64
|
return { $type, $value: mapObject(value, dehydrate, hydrations) };
|
|
65
|
-
throw new
|
|
65
|
+
throw new ValueError(`Cannot dehydrate object`, value);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
return value;
|
package/util/map.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AssertionError } from "../error/AssertionError.js";
|
|
2
1
|
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
+
import { ValueError } from "../error/ValueError.js";
|
|
3
3
|
import { isIterable, limitItems } from "./iterate.js";
|
|
4
4
|
/** Class for a `Map` that cannot be changed (so you can extend `Map` while implementing `ImmutableMap`). */
|
|
5
5
|
export const ImmutableMap = Map;
|
|
@@ -8,14 +8,14 @@ export const isMap = (value) => value instanceof Map;
|
|
|
8
8
|
/** Assert that a value is a `Map` instance. */
|
|
9
9
|
export function assertMap(value) {
|
|
10
10
|
if (!isMap(value))
|
|
11
|
-
throw new
|
|
11
|
+
throw new ValueError("Must be map", value);
|
|
12
12
|
}
|
|
13
13
|
/** Is an unknown value a key for an item in a map? */
|
|
14
14
|
export const isMapItem = (map, key) => map.has(key);
|
|
15
15
|
/** Assert that an unknown value is a key for an item in a map. */
|
|
16
16
|
export function assertMapItem(map, key) {
|
|
17
17
|
if (!isMapItem(map, key))
|
|
18
|
-
throw new
|
|
18
|
+
throw new ValueError("Must be map item", key);
|
|
19
19
|
}
|
|
20
20
|
export function getMap(input) {
|
|
21
21
|
return isMap(input) ? input : new Map(isIterable(input) ? input : Object.entries(input));
|
package/util/null.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
/** Function that always returns null. */
|
|
3
3
|
export const getNull = () => null;
|
|
4
4
|
/** Is a value null? */
|
|
@@ -6,14 +6,14 @@ export const isNull = (value) => value === null;
|
|
|
6
6
|
/** Assert that a value is not null. */
|
|
7
7
|
export function assertNull(value) {
|
|
8
8
|
if (value !== null)
|
|
9
|
-
throw new
|
|
9
|
+
throw new ValueError("Must be null", value);
|
|
10
10
|
}
|
|
11
11
|
/** Is a value not null? */
|
|
12
12
|
export const notNull = (value) => value !== null;
|
|
13
13
|
/** Assert that a value is not null. */
|
|
14
14
|
export function assertNotNull(value) {
|
|
15
15
|
if (value === null)
|
|
16
|
-
throw new
|
|
16
|
+
throw new ValueError("Must not be null", value);
|
|
17
17
|
}
|
|
18
18
|
/** Get the not-nullish version of value. */
|
|
19
19
|
export function getNotNull(value) {
|
|
@@ -25,14 +25,14 @@ export const isNullish = (value) => value === null || value === undefined;
|
|
|
25
25
|
/** Assert that a value is not nullish. */
|
|
26
26
|
export function assertNullish(value) {
|
|
27
27
|
if (value !== null && value !== undefined)
|
|
28
|
-
throw new
|
|
28
|
+
throw new ValueError("Must be null or undefined", value);
|
|
29
29
|
}
|
|
30
30
|
/** Is a value not nullish? */
|
|
31
31
|
export const notNullish = (value) => value !== null && value !== undefined;
|
|
32
32
|
/** Assert that a value is not nullish. */
|
|
33
33
|
export function assertNotNullish(value) {
|
|
34
34
|
if (value === null || value === undefined)
|
|
35
|
-
throw new
|
|
35
|
+
throw new ValueError("Must not be null or undefined", value);
|
|
36
36
|
}
|
|
37
37
|
/** Get the not-nullish version of value. */
|
|
38
38
|
export function getNotNullish(value) {
|
package/util/object.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
import { isIterable } from "./iterate.js";
|
|
3
3
|
/** Is an unknown value an unknown object? */
|
|
4
4
|
export const isObject = (value) => typeof value === "object" && value !== null;
|
|
5
5
|
/** Assert that a value is an object */
|
|
6
6
|
export function assertObject(value) {
|
|
7
7
|
if (!isObject(value))
|
|
8
|
-
throw new
|
|
8
|
+
throw new ValueError("Must be object", value);
|
|
9
9
|
}
|
|
10
10
|
/** Is an unknown value a plain object? */
|
|
11
11
|
export function isPlainObject(value) {
|
|
@@ -18,14 +18,14 @@ export function isPlainObject(value) {
|
|
|
18
18
|
/** Assert that an unknown value is a plain object */
|
|
19
19
|
export function assertPlainObject(value) {
|
|
20
20
|
if (!isPlainObject(value))
|
|
21
|
-
throw new
|
|
21
|
+
throw new ValueError(`Must be plain object`, value);
|
|
22
22
|
}
|
|
23
23
|
/** Is an unknown value the key for an own prop of an object. */
|
|
24
24
|
export const isProp = (obj, key) => Object.hasOwn(obj, key);
|
|
25
25
|
/** Assert that an unknown value is the key for an own prop of an object. */
|
|
26
26
|
export function assertProp(obj, key) {
|
|
27
27
|
if (!isProp(obj, key))
|
|
28
|
-
throw new
|
|
28
|
+
throw new ValueError("Must be object prop", key);
|
|
29
29
|
}
|
|
30
30
|
/** Turn a possible object into an object. */
|
|
31
31
|
export function getObject(obj) {
|
package/util/path.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
/** Is a string path an absolute path? */
|
|
3
3
|
export const isAbsolutePath = (path) => path.startsWith("/");
|
|
4
4
|
/** Is a string path an absolute path? */
|
|
@@ -22,7 +22,7 @@ export function getPath(path, base = _LOCATION) {
|
|
|
22
22
|
return cleanPath(new URL(path, `http://j.com${typeof base === "string" ? base : base.pathname}/`).pathname);
|
|
23
23
|
}
|
|
24
24
|
catch {
|
|
25
|
-
throw new
|
|
25
|
+
throw new ValueError("Invalid path", path);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
const _LOCATION = typeof window === "object" ? window.location : "/";
|
package/util/serialise.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
import { isArray } from "./array.js";
|
|
3
3
|
import { getPrototype, isObject } from "./object.js";
|
|
4
4
|
const R_QUOTE = /"/g;
|
|
@@ -39,7 +39,7 @@ export function serialise(value) {
|
|
|
39
39
|
const props = Object.entries(value).map(serialiseEntry).sort();
|
|
40
40
|
return `{${type ? `"$type":${escapeString(type)}${props.length ? "," : ""}` : ""}${props.join(",")}}`;
|
|
41
41
|
}
|
|
42
|
-
throw new
|
|
42
|
+
throw new ValueError("Cannot serialize value", value);
|
|
43
43
|
}
|
|
44
44
|
const serialiseEntry = ([key, value]) => `${escapeString(key)}:${serialise(value)}`;
|
|
45
45
|
const escapeString = (str) => `"${str.replace(R_QUOTE, `\\"`)}"`;
|
package/util/set.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
import { limitItems } from "./iterate.js";
|
|
3
3
|
/** Is an unknown value a set? */
|
|
4
4
|
export const isSet = (value) => value instanceof Set;
|
|
5
5
|
/** Assert that a value is a `Set` instance. */
|
|
6
6
|
export function assertSet(value) {
|
|
7
7
|
if (!isSet(value))
|
|
8
|
-
throw new
|
|
8
|
+
throw new ValueError(`Must be set`, value);
|
|
9
9
|
}
|
|
10
10
|
/** Is an unknown value an item in a set? */
|
|
11
11
|
export const isSetItem = (set, item) => set.has(item);
|
|
12
12
|
/** Assert that an unknown value is an item in a set. */
|
|
13
13
|
export function assertSetItem(set, item) {
|
|
14
14
|
if (!isSetItem(set, item))
|
|
15
|
-
throw new
|
|
15
|
+
throw new ValueError("Must be set item", item);
|
|
16
16
|
}
|
|
17
17
|
/** Convert an iterable to a `Set` (if it's already a `Set` it passes through unchanged). */
|
|
18
18
|
export function getSet(iterable) {
|
package/util/source.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
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.
|
|
@@ -17,6 +17,6 @@ export function getOptionalSource(type, value) {
|
|
|
17
17
|
export function getSource(type, data) {
|
|
18
18
|
const source = getOptionalSource(type, data);
|
|
19
19
|
if (!source)
|
|
20
|
-
throw new
|
|
20
|
+
throw new ValueError(`Source "${type.name}" not found`, data);
|
|
21
21
|
return source;
|
|
22
22
|
}
|
package/util/string.d.ts
CHANGED
|
@@ -72,7 +72,7 @@ export declare const getOptionalSlug: (str: string) => string | undefined;
|
|
|
72
72
|
export declare function getSlug(str: string): string;
|
|
73
73
|
/** Convert a string to a unique ref e.g. `abc123`, or return `undefined` if conversion resulted in an empty ref. */
|
|
74
74
|
export declare const getOptionalRef: (str: string) => string | undefined;
|
|
75
|
-
/** Convert a string to a unique ref e.g. `abc123`, or throw `
|
|
75
|
+
/** Convert a string to a unique ref e.g. `abc123`, or throw `ValueError` if conversion resulted in an empty ref. */
|
|
76
76
|
export declare function getRef(str: string): string;
|
|
77
77
|
/**
|
|
78
78
|
* Return an array of the separate words and "quoted phrases" found in a string.
|
|
@@ -100,8 +100,8 @@ export declare function limitString(str: string, maxLength: number, append?: str
|
|
|
100
100
|
* - Excess segments in `String.prototype.split()` is counterintuitive because further parts are thrown away.
|
|
101
101
|
* - Excess segments in `splitString()` are concatenated onto the last segment (set `max` to `null` if you want infinite segments).
|
|
102
102
|
*
|
|
103
|
-
* @throws
|
|
104
|
-
* @throws
|
|
103
|
+
* @throws ValueError if `min` isn't met.
|
|
104
|
+
* @throws ValueError if any of the segments are empty.
|
|
105
105
|
*/
|
|
106
106
|
export declare function splitString(str: string, separator: string, min: 1, max: 1): readonly [string];
|
|
107
107
|
export declare function splitString(str: string, separator: string, min: 2, max: 2): readonly [string, string];
|
package/util/string.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable no-control-regex */
|
|
2
|
-
import { AssertionError } from "../error/AssertionError.js";
|
|
3
2
|
import { ValueError } from "../error/ValueError.js";
|
|
4
3
|
import { getArray, isArray } from "./array.js";
|
|
5
4
|
import { formatDate, isDate } from "./date.js";
|
|
@@ -51,7 +50,7 @@ export const isStringLength = (str, min = 1, max = Infinity) => str.length >= mi
|
|
|
51
50
|
/** Assert that a value has a specific length (or length is in a specific range). */
|
|
52
51
|
export function assertStringLength(str, min = 1, max = Infinity) {
|
|
53
52
|
if (!isString(str) || !isStringLength(str, min, max))
|
|
54
|
-
throw new
|
|
53
|
+
throw new ValueError(`Must be string with length ${formatRange(min, max)}`, str);
|
|
55
54
|
}
|
|
56
55
|
/** Get a string if it has the specified minimum length. */
|
|
57
56
|
export function getStringLength(str, min = 1, max = Infinity) {
|
|
@@ -111,21 +110,21 @@ export const simplifyString = (str) => str
|
|
|
111
110
|
.toLowerCase();
|
|
112
111
|
/** Convert a string to a `kebab-case` URL slug, or return `undefined` if conversion resulted in an empty ref. */
|
|
113
112
|
export const getOptionalSlug = (str) => simplifyString(str).replace(/ /g, "-") || undefined;
|
|
114
|
-
/* Convert a string to a `kebab-case` URL slug, or throw `
|
|
113
|
+
/* Convert a string to a `kebab-case` URL slug, or throw `ValueError` if conversion resulted in an empty ref. */
|
|
115
114
|
export function getSlug(str) {
|
|
116
115
|
const slug = getOptionalSlug(str);
|
|
117
116
|
if (slug)
|
|
118
117
|
return slug;
|
|
119
|
-
throw new
|
|
118
|
+
throw new ValueError("Invalid slug", str);
|
|
120
119
|
}
|
|
121
120
|
/** Convert a string to a unique ref e.g. `abc123`, or return `undefined` if conversion resulted in an empty ref. */
|
|
122
121
|
export const getOptionalRef = (str) => simplifyString(str).replace(/ /g, "") || undefined;
|
|
123
|
-
/** Convert a string to a unique ref e.g. `abc123`, or throw `
|
|
122
|
+
/** Convert a string to a unique ref e.g. `abc123`, or throw `ValueError` if conversion resulted in an empty ref. */
|
|
124
123
|
export function getRef(str) {
|
|
125
124
|
const ref = getOptionalRef(str);
|
|
126
125
|
if (ref)
|
|
127
126
|
return ref;
|
|
128
|
-
throw new
|
|
127
|
+
throw new ValueError("Invalid string ref", str);
|
|
129
128
|
}
|
|
130
129
|
/**
|
|
131
130
|
* Return an array of the separate words and "quoted phrases" found in a string.
|
|
@@ -168,6 +167,6 @@ export function splitString(str, separator, min = 1, max = Infinity) {
|
|
|
168
167
|
if (segments.length > max)
|
|
169
168
|
segments.splice(max - 1, segments.length, segments.slice(max - 1).join(separator));
|
|
170
169
|
if (segments.length < min || !segments.every(Boolean))
|
|
171
|
-
throw new
|
|
170
|
+
throw new ValueError(`Must be string with ${formatRange(min, max)} non-empty segments separated by "${separator}"`, str);
|
|
172
171
|
return segments;
|
|
173
172
|
}
|
package/util/template.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
1
2
|
import { EMPTY_DATA } from "./data.js";
|
|
2
3
|
import { setMapItem } from "./map.js";
|
|
3
4
|
import { isObject } from "./object.js";
|
|
@@ -27,7 +28,7 @@ function _split(template) {
|
|
|
27
28
|
const placeholder = matches[i];
|
|
28
29
|
const post = matches[i + 1];
|
|
29
30
|
if (i > 1 && !pre.length)
|
|
30
|
-
throw new
|
|
31
|
+
throw new ValueError("Placeholders must be separated by at least one character", template);
|
|
31
32
|
const name = placeholder === "*" ? String(asterisks++) : R_NAME.exec(placeholder)?.[0] || "";
|
|
32
33
|
chunks.push({ pre, placeholder, name, post });
|
|
33
34
|
}
|
package/util/time.js
CHANGED
|
@@ -98,7 +98,7 @@ export function getOptionalTime(possible) {
|
|
|
98
98
|
export function getTime(possible) {
|
|
99
99
|
const time = getOptionalTime(possible);
|
|
100
100
|
if (!time)
|
|
101
|
-
throw new ValueError(`
|
|
101
|
+
throw new ValueError(`Invalid time`, possible);
|
|
102
102
|
return time;
|
|
103
103
|
}
|
|
104
104
|
/** Get the time as in `hh:mm` format (hours, minutes), e.g. `13.59` */
|
package/util/units.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AssertionError } from "../error/AssertionError.js";
|
|
2
1
|
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
+
import { ValueError } from "../error/ValueError.js";
|
|
3
3
|
import { DAY, HOUR, MILLION, MINUTE, MONTH, NNBSP, SECOND, WEEK, YEAR } from "./constants.js";
|
|
4
4
|
import { ImmutableMap } from "./map.js";
|
|
5
5
|
import { formatQuantity, pluralizeQuantity } from "./number.js";
|
|
@@ -63,7 +63,7 @@ export class Unit {
|
|
|
63
63
|
if (thisToBase)
|
|
64
64
|
return base._toUnit(_convert(amount, thisToBase), unit);
|
|
65
65
|
// Cannot convert.
|
|
66
|
-
throw new
|
|
66
|
+
throw new ValueError(`Cannot convert "${this.key}" to "${unit.key}"`);
|
|
67
67
|
}
|
|
68
68
|
/** Format an amount with a given unit of measure, e.g. `12 kg` or `29.5 l` */
|
|
69
69
|
format(amount, options) {
|