shelving 1.130.1 → 1.131.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/api/Resource.js +2 -2
- package/db/ItemStore.js +2 -2
- package/db/Provider.js +5 -5
- package/db/QueryStore.js +3 -3
- package/db/ValidationProvider.js +3 -3
- package/error/ConflictError.d.ts +6 -0
- package/error/ConflictError.js +9 -0
- package/error/EnhancedError.d.ts +1 -0
- package/error/EnhancedError.js +1 -0
- package/error/ForbiddenError.d.ts +6 -0
- package/error/ForbiddenError.js +9 -0
- package/error/NotFoundError.d.ts +6 -0
- package/error/NotFoundError.js +9 -0
- package/error/{UnimplementedError.d.ts → NotImplementedError.d.ts} +2 -1
- package/error/{UnimplementedError.js → NotImplementedError.js} +3 -2
- package/error/UnauthorizedError.d.ts +6 -0
- package/error/UnauthorizedError.js +9 -0
- package/error/{ValueError.d.ts → ValidationError.d.ts} +2 -1
- package/error/{ValueError.js → ValidationError.js} +3 -2
- package/error/index.d.ts +6 -5
- package/error/index.js +6 -5
- package/firestore/lite/FirestoreLiteProvider.js +3 -3
- package/iterate/InspectIterator.js +4 -4
- package/package.json +1 -1
- package/react/createCacheContext.js +2 -2
- package/sequence/InspectSequence.js +4 -4
- package/util/array.js +7 -7
- package/util/assert.js +3 -3
- package/util/async.js +4 -4
- package/util/boolean.js +6 -6
- package/util/class.js +2 -2
- package/util/color.js +3 -3
- package/util/data.js +3 -3
- package/util/date.js +3 -3
- package/util/dictionary.js +5 -5
- package/util/entity.js +2 -2
- package/util/file.js +2 -2
- package/util/function.js +2 -2
- package/util/hydrate.js +3 -3
- package/util/link.js +2 -2
- package/util/map.js +5 -5
- package/util/null.js +5 -5
- package/util/number.js +6 -6
- package/util/object.js +4 -4
- package/util/optional.js +2 -2
- package/util/path.js +2 -2
- package/util/regexp.js +4 -4
- package/util/sequence.js +2 -2
- package/util/serialise.js +2 -2
- package/util/set.js +3 -3
- package/util/source.js +2 -2
- package/util/string.js +6 -6
- package/util/template.js +2 -2
- package/util/time.js +2 -2
- package/util/undefined.js +2 -2
- package/util/units.js +4 -4
- package/util/url.js +3 -3
- package/util/validate.js +2 -2
- package/error/PermissionError.d.ts +0 -5
- package/error/PermissionError.js +0 -8
- package/error/RequiredError.d.ts +0 -5
- package/error/RequiredError.js +0 -8
- package/error/StateError.d.ts +0 -5
- package/error/StateError.js +0 -8
package/api/Resource.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.js";
|
|
2
2
|
import { Feedback } from "../feedback/Feedback.js";
|
|
3
3
|
import { UNDEFINED_VALIDATOR } from "../util/validate.js";
|
|
4
4
|
/**
|
|
@@ -41,7 +41,7 @@ export class Resource {
|
|
|
41
41
|
}
|
|
42
42
|
catch (thrown) {
|
|
43
43
|
if (thrown instanceof Feedback)
|
|
44
|
-
throw new
|
|
44
|
+
throw new ValidationError("Invalid result for resource", thrown);
|
|
45
45
|
throw thrown;
|
|
46
46
|
}
|
|
47
47
|
}
|
package/db/ItemStore.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NotFoundError } from "../error/NotFoundError.js";
|
|
2
2
|
import { BooleanStore } from "../store/BooleanStore.js";
|
|
3
3
|
import { OptionalDataStore } from "../store/DataStore.js";
|
|
4
4
|
import { NONE } from "../util/constants.js";
|
|
@@ -14,7 +14,7 @@ export class ItemStore extends OptionalDataStore {
|
|
|
14
14
|
get data() {
|
|
15
15
|
const item = this.value;
|
|
16
16
|
if (!item)
|
|
17
|
-
throw new
|
|
17
|
+
throw new NotFoundError(`Item must exist in "${this.collection}"`, this.id);
|
|
18
18
|
return item;
|
|
19
19
|
}
|
|
20
20
|
/** Set the data of this store. */
|
package/db/Provider.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NotFoundError } from "../error/NotFoundError.js";
|
|
2
2
|
import { countArray, getOptionalFirstItem } from "../util/array.js";
|
|
3
3
|
/** Provider with a fully synchronous interface */
|
|
4
4
|
export class Provider {
|
|
5
5
|
requireItem(collection, id) {
|
|
6
6
|
const item = this.getItem(collection, id);
|
|
7
7
|
if (!item)
|
|
8
|
-
throw new
|
|
8
|
+
throw new NotFoundError(`Item must exist in "${collection}"`, id);
|
|
9
9
|
return item;
|
|
10
10
|
}
|
|
11
11
|
countQuery(collection, query) {
|
|
@@ -17,7 +17,7 @@ export class Provider {
|
|
|
17
17
|
requireFirst(collection, query) {
|
|
18
18
|
const first = this.getFirst(collection, query);
|
|
19
19
|
if (!first)
|
|
20
|
-
throw new
|
|
20
|
+
throw new NotFoundError(`First item must exist in "${collection}"`, query);
|
|
21
21
|
return first;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -26,7 +26,7 @@ export class AsyncProvider {
|
|
|
26
26
|
async requireItem(collection, id) {
|
|
27
27
|
const item = await this.getItem(collection, id);
|
|
28
28
|
if (!item)
|
|
29
|
-
throw new
|
|
29
|
+
throw new NotFoundError(`Item must exist in "${collection}"`, id);
|
|
30
30
|
return item;
|
|
31
31
|
}
|
|
32
32
|
async countQuery(collection, query) {
|
|
@@ -38,7 +38,7 @@ export class AsyncProvider {
|
|
|
38
38
|
async requireFirst(collection, query) {
|
|
39
39
|
const first = await this.getFirst(collection, query);
|
|
40
40
|
if (!first)
|
|
41
|
-
throw new
|
|
41
|
+
throw new NotFoundError(`First item must exist in "${collection}"`, query);
|
|
42
42
|
return first;
|
|
43
43
|
}
|
|
44
44
|
}
|
package/db/QueryStore.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { collection, query } from "firebase/firestore";
|
|
2
|
-
import {
|
|
2
|
+
import { NotFoundError } from "../error/NotFoundError.js";
|
|
3
3
|
import { ArrayStore } from "../store/ArrayStore.js";
|
|
4
4
|
import { BooleanStore } from "../store/BooleanStore.js";
|
|
5
5
|
import { NONE } from "../util/constants.js";
|
|
@@ -21,14 +21,14 @@ export class QueryStore extends ArrayStore {
|
|
|
21
21
|
get first() {
|
|
22
22
|
const first = this.optionalFirst;
|
|
23
23
|
if (!first)
|
|
24
|
-
throw new
|
|
24
|
+
throw new NotFoundError(`First item must exist in "${collection}"`, query);
|
|
25
25
|
return first;
|
|
26
26
|
}
|
|
27
27
|
/** Get the last item in this store. */
|
|
28
28
|
get last() {
|
|
29
29
|
const last = this.optionalLast;
|
|
30
30
|
if (!last)
|
|
31
|
-
throw new
|
|
31
|
+
throw new NotFoundError(`Last item must exist in "${collection}"`, query);
|
|
32
32
|
return last;
|
|
33
33
|
}
|
|
34
34
|
constructor(collection, query, provider, memory) {
|
package/db/ValidationProvider.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.js";
|
|
2
2
|
import { Feedback } from "../feedback/Feedback.js";
|
|
3
3
|
import { updateData } from "../util/update.js";
|
|
4
4
|
import { validateWithContext } from "../util/validate.js";
|
|
@@ -124,7 +124,7 @@ function _validateItem(collection, unsafeEntity, schema) {
|
|
|
124
124
|
catch (thrown) {
|
|
125
125
|
if (!(thrown instanceof Feedback))
|
|
126
126
|
throw thrown;
|
|
127
|
-
throw new
|
|
127
|
+
throw new ValidationError(`Invalid data for "${collection}"`, thrown.message);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
/** Validate a set of entities for this query reference. */
|
|
@@ -146,5 +146,5 @@ function* _yieldValidItems(collection, unsafeEntities, schema) {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
if (invalid)
|
|
149
|
-
throw new
|
|
149
|
+
throw new ValidationError(`Invalid data for "${collection}"`, messages);
|
|
150
150
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EnhancedError } from "./EnhancedError.js";
|
|
2
|
+
/** Thrown if the state of the program is not correct to execute a given operation. */
|
|
3
|
+
export declare class ConflictError extends EnhancedError {
|
|
4
|
+
readonly code = 509;
|
|
5
|
+
constructor(message?: string, context?: unknown);
|
|
6
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EnhancedError } from "./EnhancedError.js";
|
|
2
|
+
/** Thrown if the state of the program is not correct to execute a given operation. */
|
|
3
|
+
export class ConflictError extends EnhancedError {
|
|
4
|
+
code = 509;
|
|
5
|
+
constructor(message = "Conflict", context) {
|
|
6
|
+
super(message, context);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
ConflictError.prototype.name = "ConflictError";
|
package/error/EnhancedError.d.ts
CHANGED
package/error/EnhancedError.js
CHANGED
|
@@ -5,6 +5,7 @@ import { debug } from "../util/debug.js";
|
|
|
5
5
|
* - Context is converted to a string using `debug()`
|
|
6
6
|
*/
|
|
7
7
|
export class EnhancedError extends Error {
|
|
8
|
+
code = 500;
|
|
8
9
|
context;
|
|
9
10
|
constructor(message, context) {
|
|
10
11
|
const debugged = context !== undefined ? debug(context, 2) : "";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EnhancedError } from "./EnhancedError.js";
|
|
2
|
+
/** Thrown if an operation failed because the user is logged in but does not have sufficient privileges to access something. */
|
|
3
|
+
export declare class ForbiddenError extends EnhancedError {
|
|
4
|
+
readonly code = 403;
|
|
5
|
+
constructor(message?: string, context?: unknown);
|
|
6
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EnhancedError } from "./EnhancedError.js";
|
|
2
|
+
/** Thrown if an operation failed because the user is logged in but does not have sufficient privileges to access something. */
|
|
3
|
+
export class ForbiddenError extends EnhancedError {
|
|
4
|
+
code = 403;
|
|
5
|
+
constructor(message = "Forbidden", context) {
|
|
6
|
+
super(message, context);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
ForbiddenError.prototype.name = "ForbiddenError";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EnhancedError } from "./EnhancedError.js";
|
|
2
|
+
/** Thrown if if a value is required but doesn't exist. */
|
|
3
|
+
export class NotFoundError extends EnhancedError {
|
|
4
|
+
code = 404;
|
|
5
|
+
constructor(message = "Not found", context) {
|
|
6
|
+
super(message, context);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
NotFoundError.prototype.name = "NotFoundError";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EnhancedError } from "./EnhancedError.js";
|
|
2
2
|
/** Error thrown when functionality is called but is not implemented by an interface. */
|
|
3
|
-
export declare class
|
|
3
|
+
export declare class NotImplementedError extends EnhancedError {
|
|
4
|
+
readonly code = 501;
|
|
4
5
|
constructor(message?: string, value?: unknown);
|
|
5
6
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { EnhancedError } from "./EnhancedError.js";
|
|
2
2
|
/** Error thrown when functionality is called but is not implemented by an interface. */
|
|
3
|
-
export class
|
|
3
|
+
export class NotImplementedError extends EnhancedError {
|
|
4
|
+
code = 501;
|
|
4
5
|
constructor(message = "Not implemented", value) {
|
|
5
6
|
super(message, value);
|
|
6
7
|
}
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
+
NotImplementedError.prototype.name = "NotImplementedError";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EnhancedError } from "./EnhancedError.js";
|
|
2
|
+
/** Thrown if an operation failed because the user is logged in but does not have sufficient privileges to access something. */
|
|
3
|
+
export declare class UnauthorizedError extends EnhancedError {
|
|
4
|
+
readonly code = 403;
|
|
5
|
+
constructor(message?: string, context?: unknown);
|
|
6
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EnhancedError } from "./EnhancedError.js";
|
|
2
|
+
/** Thrown if an operation failed because the user is logged in but does not have sufficient privileges to access something. */
|
|
3
|
+
export class UnauthorizedError extends EnhancedError {
|
|
4
|
+
code = 403;
|
|
5
|
+
constructor(message = "Unauthorized", context) {
|
|
6
|
+
super(message, context);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
UnauthorizedError.prototype.name = "UnauthorizedError";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EnhancedError } from "./EnhancedError.js";
|
|
2
2
|
/** Error thrown when a value isn't valid. */
|
|
3
|
-
export declare class
|
|
3
|
+
export declare class ValidationError extends EnhancedError {
|
|
4
|
+
readonly code = 422;
|
|
4
5
|
constructor(message?: string, context?: unknown);
|
|
5
6
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { EnhancedError } from "./EnhancedError.js";
|
|
2
2
|
/** Error thrown when a value isn't valid. */
|
|
3
|
-
export class
|
|
3
|
+
export class ValidationError extends EnhancedError {
|
|
4
|
+
code = 422;
|
|
4
5
|
constructor(message = "Invalid value", context) {
|
|
5
6
|
super(message, context);
|
|
6
7
|
}
|
|
7
8
|
}
|
|
8
|
-
|
|
9
|
+
ValidationError.prototype.name = "ValidationError";
|
package/error/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from "./EnhancedError.js";
|
|
2
|
-
export * from "./
|
|
2
|
+
export * from "./ConflictError.js";
|
|
3
3
|
export * from "./ConnectionError.js";
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
6
|
-
export * from "./
|
|
7
|
-
export * from "./
|
|
4
|
+
export * from "./ForbiddenError.js";
|
|
5
|
+
export * from "./UnauthorizedError.js";
|
|
6
|
+
export * from "./NotFoundError.js";
|
|
7
|
+
export * from "./NotImplementedError.js";
|
|
8
|
+
export * from "./ValidationError.js";
|
package/error/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from "./EnhancedError.js";
|
|
2
|
-
export * from "./
|
|
2
|
+
export * from "./ConflictError.js";
|
|
3
3
|
export * from "./ConnectionError.js";
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
6
|
-
export * from "./
|
|
7
|
-
export * from "./
|
|
4
|
+
export * from "./ForbiddenError.js";
|
|
5
|
+
export * from "./UnauthorizedError.js";
|
|
6
|
+
export * from "./NotFoundError.js";
|
|
7
|
+
export * from "./NotImplementedError.js";
|
|
8
|
+
export * from "./ValidationError.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { addDoc, arrayRemove, arrayUnion, collection, deleteDoc, doc, documentId, getCount, getDoc, getDocs, increment, limit, orderBy, query, setDoc, updateDoc, where, } from "firebase/firestore/lite";
|
|
2
2
|
import { AsyncProvider } from "../../db/Provider.js";
|
|
3
|
-
import {
|
|
3
|
+
import { NotImplementedError } from "../../error/NotImplementedError.js";
|
|
4
4
|
import { getItem } from "../../util/item.js";
|
|
5
5
|
import { getObject } from "../../util/object.js";
|
|
6
6
|
import { getFilters, getLimit, getOrders } from "../../util/query.js";
|
|
@@ -76,7 +76,7 @@ export class FirestoreLiteProvider extends AsyncProvider {
|
|
|
76
76
|
return _getOptionalItem(snapshot);
|
|
77
77
|
}
|
|
78
78
|
getItemSequence() {
|
|
79
|
-
throw new
|
|
79
|
+
throw new NotImplementedError("FirestoreLiteProvider does not support realtime subscriptions");
|
|
80
80
|
}
|
|
81
81
|
async addItem(c, data) {
|
|
82
82
|
const reference = await addDoc(collection(this._firestore, c), data);
|
|
@@ -100,7 +100,7 @@ export class FirestoreLiteProvider extends AsyncProvider {
|
|
|
100
100
|
return snapshot.docs.map(_getItem);
|
|
101
101
|
}
|
|
102
102
|
getQuerySequence() {
|
|
103
|
-
throw new
|
|
103
|
+
throw new NotImplementedError("FirestoreLiteProvider does not support realtime subscriptions");
|
|
104
104
|
}
|
|
105
105
|
async setQuery(c, q, data) {
|
|
106
106
|
const snapshot = await getDocs(_getQuery(this._firestore, c, q));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConflictError } from "../error/ConflictError.js";
|
|
2
2
|
import { ThroughIterator } from "./ThroughIterator.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 InspectIterator extends ThroughIterator {
|
|
|
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 ConflictError("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 ConflictError("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 ConflictError("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 { ConflictError } from "../error/ConflictError.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 ConflictError("useCache() must be used inside <Cache>");
|
|
14
14
|
return cache;
|
|
15
15
|
},
|
|
16
16
|
CacheContext({ children }) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConflictError } from "../error/ConflictError.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 ConflictError("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 ConflictError("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 ConflictError("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 {
|
|
2
|
-
import {
|
|
1
|
+
import { NotFoundError } from "../error/NotFoundError.js";
|
|
2
|
+
import { ValidationError } from "../error/ValidationError.js";
|
|
3
3
|
import { omitItems, pickItems } from "./iterate.js";
|
|
4
4
|
import { formatRange } from "./number.js";
|
|
5
5
|
/** Is an unknown value an array? */
|
|
@@ -9,7 +9,7 @@ export function isArray(value) {
|
|
|
9
9
|
/** Assert that an unknown value is an array. */
|
|
10
10
|
export function assertArray(arr) {
|
|
11
11
|
if (!isArray(arr))
|
|
12
|
-
throw new
|
|
12
|
+
throw new ValidationError("Must be array", arr);
|
|
13
13
|
}
|
|
14
14
|
/** Is an unknown value an item in a specified array? */
|
|
15
15
|
export function isArrayItem(arr, item) {
|
|
@@ -18,7 +18,7 @@ export function isArrayItem(arr, item) {
|
|
|
18
18
|
/** Assert that an unknown value is an item in a specified array. */
|
|
19
19
|
export function assertArrayItem(arr, item) {
|
|
20
20
|
if (!isArrayItem(arr, item))
|
|
21
|
-
throw new
|
|
21
|
+
throw new ValidationError("Must be array item", item);
|
|
22
22
|
}
|
|
23
23
|
/** Convert an iterable to an array (if its not already an array). */
|
|
24
24
|
export function getArray(items) {
|
|
@@ -57,7 +57,7 @@ export function getOptionalFirstItem(items) {
|
|
|
57
57
|
export function getFirstItem(items) {
|
|
58
58
|
const item = getOptionalFirstItem(items);
|
|
59
59
|
if (item === undefined)
|
|
60
|
-
throw new
|
|
60
|
+
throw new NotFoundError("First item is required");
|
|
61
61
|
return item;
|
|
62
62
|
}
|
|
63
63
|
/** Get the last item from an array or iterable, or `undefined` if it didn't exist. */
|
|
@@ -71,7 +71,7 @@ export function getOptionalLastItem(items) {
|
|
|
71
71
|
export function getLastItem(items) {
|
|
72
72
|
const item = getOptionalLastItem(items);
|
|
73
73
|
if (item === undefined)
|
|
74
|
-
throw new
|
|
74
|
+
throw new NotFoundError("Last item is required");
|
|
75
75
|
return item;
|
|
76
76
|
}
|
|
77
77
|
/** Get the next item in an array or iterable. */
|
|
@@ -144,7 +144,7 @@ export function isArrayLength(arr, min = 1, max = Number.POSITIVE_INFINITY) {
|
|
|
144
144
|
}
|
|
145
145
|
export function assertArrayLength(arr, min = 1, max = Number.POSITIVE_INFINITY) {
|
|
146
146
|
if (!isArray(arr) || !isArrayLength(arr, min, max))
|
|
147
|
-
throw new
|
|
147
|
+
throw new ValidationError(`Must be array with length ${formatRange(min, max)}`, arr);
|
|
148
148
|
}
|
|
149
149
|
export function getArrayLength(arr, min = 1, max = Number.POSITIVE_INFINITY) {
|
|
150
150
|
assertArrayLength(arr, min, max);
|
package/util/assert.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.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 ValidationError("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 ValidationError("Must not be equal", { left, right });
|
|
11
11
|
}
|
package/util/async.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.js";
|
|
2
2
|
/** Is a value an asynchronous value implementing a `then()` function. */
|
|
3
3
|
export function isAsync(value) {
|
|
4
4
|
return typeof value === "object" && value !== null && typeof value.then === "function";
|
|
@@ -20,17 +20,17 @@ export function throwAsync(value) {
|
|
|
20
20
|
/** Assert a synchronous value. */
|
|
21
21
|
export function assertNotAsync(value) {
|
|
22
22
|
if (isAsync(value))
|
|
23
|
-
throw new
|
|
23
|
+
throw new ValidationError("Must be synchronous", value);
|
|
24
24
|
}
|
|
25
25
|
/** Assert an asynchronous value. */
|
|
26
26
|
export function assertAsync(value) {
|
|
27
27
|
if (!isAsync(value))
|
|
28
|
-
throw new
|
|
28
|
+
throw new ValidationError("Must be asynchronous", value);
|
|
29
29
|
}
|
|
30
30
|
/** Assert a promise. */
|
|
31
31
|
export function assertPromise(value) {
|
|
32
32
|
if (!(value instanceof Promise))
|
|
33
|
-
throw new
|
|
33
|
+
throw new ValidationError("Must be promise", value);
|
|
34
34
|
}
|
|
35
35
|
/** Run any queued microtasks now. */
|
|
36
36
|
export function runMicrotasks() {
|
package/util/boolean.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.js";
|
|
2
2
|
/** Is a value a boolean? */
|
|
3
3
|
export function isBoolean(value) {
|
|
4
4
|
return typeof value === "boolean";
|
|
@@ -22,25 +22,25 @@ export function isFalsey(value) {
|
|
|
22
22
|
/** Assert that a value is a boolean. */
|
|
23
23
|
export function assertBoolean(value) {
|
|
24
24
|
if (typeof value !== "boolean")
|
|
25
|
-
throw new
|
|
25
|
+
throw new ValidationError("Must be boolean", value);
|
|
26
26
|
}
|
|
27
27
|
/** Assert that a value is true. */
|
|
28
28
|
export function assertTrue(value) {
|
|
29
29
|
if (value !== true)
|
|
30
|
-
throw new
|
|
30
|
+
throw new ValidationError("Must be true", value);
|
|
31
31
|
}
|
|
32
32
|
/** Assert that a value is false. */
|
|
33
33
|
export function assertFalse(value) {
|
|
34
34
|
if (value !== false)
|
|
35
|
-
throw new
|
|
35
|
+
throw new ValidationError("Must be false", value);
|
|
36
36
|
}
|
|
37
37
|
/** Assert that a value is truthy. */
|
|
38
38
|
export function assertTruthy(value) {
|
|
39
39
|
if (!value)
|
|
40
|
-
throw new
|
|
40
|
+
throw new ValidationError("Must be truthy", value);
|
|
41
41
|
}
|
|
42
42
|
/** Assert that a value is falsy. */
|
|
43
43
|
export function assertFalsy(value) {
|
|
44
44
|
if (value)
|
|
45
|
-
throw new
|
|
45
|
+
throw new ValidationError("Must be falsy", value);
|
|
46
46
|
}
|
package/util/class.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.js";
|
|
2
2
|
import { debug } from "./debug.js";
|
|
3
3
|
/** Is a given value a class constructor? */
|
|
4
4
|
export function isConstructor(value) {
|
|
@@ -11,5 +11,5 @@ export function isInstance(value, type) {
|
|
|
11
11
|
/** Assert that a value is an instance of something. */
|
|
12
12
|
export function assertInstance(value, type) {
|
|
13
13
|
if (!(value instanceof type))
|
|
14
|
-
throw new
|
|
14
|
+
throw new ValidationError(`Must be instance of ${debug(type)}`, value);
|
|
15
15
|
}
|
package/util/color.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.js";
|
|
2
2
|
import { boundNumber, roundNumber } from "./number.js";
|
|
3
3
|
// Constants.
|
|
4
4
|
const DARK = 140; // Anything with a luminance > 140 is considered light.
|
|
@@ -71,7 +71,7 @@ export function isColor(value) {
|
|
|
71
71
|
/** Assert that an unknown value is a `Color` instance. */
|
|
72
72
|
export function assertColor(value) {
|
|
73
73
|
if (!isColor(value))
|
|
74
|
-
throw new
|
|
74
|
+
throw new ValidationError("Must be color", value);
|
|
75
75
|
}
|
|
76
76
|
/** Convert a possible color to a `Color` instance or `undefined` */
|
|
77
77
|
export function getOptionalColor(possible) {
|
|
@@ -81,6 +81,6 @@ export function getOptionalColor(possible) {
|
|
|
81
81
|
export function getColor(possible) {
|
|
82
82
|
const color = getOptionalColor(possible);
|
|
83
83
|
if (!color)
|
|
84
|
-
throw new
|
|
84
|
+
throw new ValidationError("Invalid color", possible);
|
|
85
85
|
return color;
|
|
86
86
|
}
|
package/util/data.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.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? */
|
|
@@ -8,14 +8,14 @@ export function isData(value) {
|
|
|
8
8
|
/** Assert that an unknown value is a data object. */
|
|
9
9
|
export function assertData(value) {
|
|
10
10
|
if (!isPlainObject(value))
|
|
11
|
-
throw new
|
|
11
|
+
throw new ValidationError("Must be data", value);
|
|
12
12
|
}
|
|
13
13
|
/** Is an unknown value the key for an own prop of a data object. */
|
|
14
14
|
export const isDataProp = (data, key) => typeof key === "string" && Object.hasOwn(data, key);
|
|
15
15
|
/** Assert that an unknown value is the key for an own prop of a data object. */
|
|
16
16
|
export function assertDataProp(data, key) {
|
|
17
17
|
if (!isDataProp(data, key))
|
|
18
|
-
throw new
|
|
18
|
+
throw new ValidationError("Must be data prop", key);
|
|
19
19
|
}
|
|
20
20
|
export function getData(input) {
|
|
21
21
|
return isIterable(input) ? Object.fromEntries(input) : input;
|
package/util/date.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValidationError } from "../error/ValidationError.js";
|
|
2
2
|
/** Is a value a date? */
|
|
3
3
|
export function isDate(value) {
|
|
4
4
|
return value instanceof Date && Number.isFinite(value.getTime());
|
|
@@ -6,7 +6,7 @@ export function isDate(value) {
|
|
|
6
6
|
/** Assert that a value is a `Date` instance. */
|
|
7
7
|
export function assertDate(value) {
|
|
8
8
|
if (!isDate(value))
|
|
9
|
-
throw new
|
|
9
|
+
throw new ValidationError("Must be date", value);
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Convert an unknown value to a valid `Date` instance, or return `undefined` if it couldn't be converted.
|
|
@@ -52,7 +52,7 @@ export function getOptionalDate(possible) {
|
|
|
52
52
|
export function getDate(possible = "now") {
|
|
53
53
|
const date = getOptionalDate(possible);
|
|
54
54
|
if (!date)
|
|
55
|
-
throw new
|
|
55
|
+
throw new ValidationError("Invalid date", possible);
|
|
56
56
|
return date;
|
|
57
57
|
}
|
|
58
58
|
/** Convert an unknown value to a timestamp (milliseconds past Unix epoch), or `undefined` if it couldn't be converted. */
|