shelving 1.135.0 → 1.136.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.d.ts +2 -2
- package/api/Resource.js +4 -4
- package/db/ItemStore.js +9 -2
- package/db/Provider.js +29 -8
- package/db/QueryStore.js +16 -4
- package/db/ValidationProvider.js +26 -26
- package/error/AssertionError.d.ts +8 -0
- package/error/AssertionError.js +12 -0
- package/error/BaseError.d.ts +19 -0
- package/error/BaseError.js +18 -0
- package/error/NetworkError.d.ts +5 -0
- package/error/NetworkError.js +9 -0
- package/error/RequestError.d.ts +32 -0
- package/error/RequestError.js +50 -0
- package/error/RequiredError.d.ts +8 -0
- package/error/RequiredError.js +12 -0
- package/error/UnexpectedError.d.ts +5 -0
- package/error/UnexpectedError.js +9 -0
- package/error/UnimplementedError.d.ts +5 -0
- package/error/UnimplementedError.js +9 -0
- package/error/ValueError.d.ts +5 -0
- package/error/ValueError.js +9 -0
- package/error/index.d.ts +8 -8
- package/error/index.js +8 -8
- package/firestore/lite/FirestoreLiteProvider.js +3 -3
- package/iterate/InspectIterator.js +14 -4
- package/markup/rule/link.js +2 -2
- package/package.json +1 -1
- package/react/createCacheContext.js +12 -13
- package/react/createDataContext.js +2 -2
- package/schema/AllowSchema.js +2 -2
- package/schema/DateSchema.d.ts +1 -1
- package/schema/DateSchema.js +12 -12
- package/schema/FileSchema.js +2 -2
- package/schema/LinkSchema.js +2 -2
- package/schema/SlugSchema.js +2 -2
- package/schema/TimeSchema.js +4 -4
- package/sequence/InspectSequence.js +14 -4
- package/store/ArrayStore.js +6 -5
- package/store/PathStore.js +4 -4
- package/test/util.js +6 -3
- package/util/array.d.ts +39 -42
- package/util/array.js +48 -82
- package/util/async.d.ts +3 -3
- package/util/async.js +7 -7
- package/util/boolean.js +6 -6
- package/util/class.d.ts +4 -0
- package/util/class.js +14 -3
- package/util/color.d.ts +3 -3
- package/util/color.js +8 -8
- package/util/data.d.ts +3 -3
- package/util/data.js +3 -3
- package/util/date.d.ts +20 -15
- package/util/date.js +87 -37
- package/util/dictionary.d.ts +12 -12
- package/util/dictionary.js +20 -19
- package/util/entity.js +2 -2
- package/util/equal.d.ts +4 -0
- package/util/equal.js +12 -1
- package/util/error.d.ts +0 -2
- package/util/error.js +0 -20
- package/util/file.d.ts +3 -3
- package/util/file.js +6 -6
- package/util/function.js +2 -2
- package/util/hydrate.js +5 -3
- package/util/index.d.ts +0 -2
- package/util/index.js +0 -2
- package/util/iterate.d.ts +13 -0
- package/util/iterate.js +48 -0
- package/util/link.d.ts +4 -4
- package/util/link.js +8 -8
- package/util/map.d.ts +4 -4
- package/util/map.js +9 -9
- package/util/null.js +5 -5
- package/util/number.d.ts +6 -11
- package/util/number.js +23 -18
- package/util/object.js +4 -4
- package/util/optional.js +2 -2
- package/util/path.d.ts +3 -3
- package/util/path.js +6 -6
- package/util/query.d.ts +4 -4
- package/util/query.js +10 -9
- package/util/regexp.d.ts +12 -12
- package/util/regexp.js +13 -12
- package/util/sequence.d.ts +0 -2
- package/util/sequence.js +0 -7
- package/util/serialise.js +2 -2
- package/util/set.js +3 -3
- package/util/source.d.ts +4 -8
- package/util/source.js +8 -12
- package/util/string.d.ts +14 -22
- package/util/string.js +27 -29
- package/util/template.js +10 -11
- package/util/time.d.ts +2 -5
- package/util/time.js +12 -13
- package/util/undefined.js +2 -2
- package/util/units.d.ts +17 -12
- package/util/units.js +61 -40
- package/util/url.d.ts +3 -3
- package/util/url.js +11 -7
- package/util/validate.d.ts +4 -4
- package/util/validate.js +4 -8
- package/error/CodedError.d.ts +0 -13
- package/error/CodedError.js +0 -21
- package/error/ConflictError.d.ts +0 -6
- package/error/ConflictError.js +0 -11
- package/error/ConnectionError.d.ts +0 -5
- package/error/ConnectionError.js +0 -10
- package/error/ForbiddenError.d.ts +0 -6
- package/error/ForbiddenError.js +0 -11
- package/error/NotFoundError.d.ts +0 -6
- package/error/NotFoundError.js +0 -11
- package/error/NotImplementedError.d.ts +0 -6
- package/error/NotImplementedError.js +0 -11
- package/error/UnauthorizedError.d.ts +0 -6
- package/error/UnauthorizedError.js +0 -11
- package/error/ValidationError.d.ts +0 -6
- package/error/ValidationError.js +0 -11
- package/util/assert.d.ts +0 -4
- package/util/assert.js +0 -11
- package/util/duration.d.ts +0 -10
- package/util/duration.js +0 -50
package/api/Resource.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Validator } from "../util/validate.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* An abstract API resource definition, used to specify types for e.g. serverless functions..
|
|
4
4
|
*
|
|
5
|
-
* @param name The name of the resource.
|
|
5
|
+
* @param name The name of the resource, e.g. `getUser`.
|
|
6
6
|
* @param payload The `Validator` the resource's payload must conform to (defaults to `undefined` if not specified).
|
|
7
7
|
* @param returns The `Validator` the resource's returned value must conform to (defaults to `undefined` if not specified).
|
|
8
8
|
*/
|
|
@@ -27,7 +27,7 @@ export declare class Resource<P = undefined, R = void> implements Validator<R> {
|
|
|
27
27
|
* Validate a result for this resource.
|
|
28
28
|
*
|
|
29
29
|
* @returns The validated result for this resource.
|
|
30
|
-
* @throws
|
|
30
|
+
* @throws ValueError if the result could not be validated.
|
|
31
31
|
*/
|
|
32
32
|
validate(unsafeResult: unknown): R;
|
|
33
33
|
}
|
package/api/Resource.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
import { Feedback } from "../feedback/Feedback.js";
|
|
3
3
|
import { UNDEFINED } from "../util/validate.js";
|
|
4
4
|
/**
|
|
5
5
|
* An abstract API resource definition, used to specify types for e.g. serverless functions..
|
|
6
6
|
*
|
|
7
|
-
* @param name The name of the resource.
|
|
7
|
+
* @param name The name of the resource, e.g. `getUser`.
|
|
8
8
|
* @param payload The `Validator` the resource's payload must conform to (defaults to `undefined` if not specified).
|
|
9
9
|
* @param returns The `Validator` the resource's returned value must conform to (defaults to `undefined` if not specified).
|
|
10
10
|
*/
|
|
@@ -33,7 +33,7 @@ export class Resource {
|
|
|
33
33
|
* Validate a result for this resource.
|
|
34
34
|
*
|
|
35
35
|
* @returns The validated result for this resource.
|
|
36
|
-
* @throws
|
|
36
|
+
* @throws ValueError if the result could not be validated.
|
|
37
37
|
*/
|
|
38
38
|
validate(unsafeResult) {
|
|
39
39
|
try {
|
|
@@ -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 ValueError(`Invalid result for resource "${this.name}"`, { received: unsafeResult, caller: this.validate });
|
|
45
45
|
throw thrown;
|
|
46
46
|
}
|
|
47
47
|
}
|
package/db/ItemStore.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RequiredError } from "../error/RequiredError.js";
|
|
2
2
|
import { BooleanStore } from "../store/BooleanStore.js";
|
|
3
3
|
import { OptionalDataStore } from "../store/DataStore.js";
|
|
4
|
+
import { getGetter } from "../util/class.js";
|
|
4
5
|
import { NONE } from "../util/constants.js";
|
|
5
6
|
import { getItem } from "../util/item.js";
|
|
6
7
|
import { runSequence } from "../util/sequence.js";
|
|
@@ -14,7 +15,13 @@ export class ItemStore extends OptionalDataStore {
|
|
|
14
15
|
get data() {
|
|
15
16
|
const item = this.value;
|
|
16
17
|
if (!item)
|
|
17
|
-
throw new
|
|
18
|
+
throw new RequiredError(`Item does not exist in collection "${this.collection}"`, {
|
|
19
|
+
store: this,
|
|
20
|
+
provider: this.provider,
|
|
21
|
+
collection: this.collection,
|
|
22
|
+
id: this.id,
|
|
23
|
+
caller: getGetter(this, "data"),
|
|
24
|
+
});
|
|
18
25
|
return item;
|
|
19
26
|
}
|
|
20
27
|
/** Set the data of this store. */
|
package/db/Provider.js
CHANGED
|
@@ -1,23 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { countArray
|
|
1
|
+
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
+
import { countArray } from "../util/array.js";
|
|
3
|
+
import { getFirstItem } from "../util/iterate.js";
|
|
3
4
|
/** Provider with a fully synchronous interface */
|
|
4
5
|
export class Provider {
|
|
5
6
|
requireItem(collection, id) {
|
|
6
7
|
const item = this.getItem(collection, id);
|
|
7
8
|
if (!item)
|
|
8
|
-
throw new
|
|
9
|
+
throw new RequiredError(`Item does not exist in collection "${collection}"`, {
|
|
10
|
+
provider: this,
|
|
11
|
+
collection,
|
|
12
|
+
id,
|
|
13
|
+
caller: this.getItem,
|
|
14
|
+
});
|
|
9
15
|
return item;
|
|
10
16
|
}
|
|
11
17
|
countQuery(collection, query) {
|
|
12
18
|
return countArray(this.getQuery(collection, query));
|
|
13
19
|
}
|
|
14
20
|
getFirst(collection, query) {
|
|
15
|
-
return
|
|
21
|
+
return getFirstItem(this.getQuery(collection, { ...query, $limit: 1 }));
|
|
16
22
|
}
|
|
17
23
|
requireFirst(collection, query) {
|
|
18
24
|
const first = this.getFirst(collection, query);
|
|
19
25
|
if (!first)
|
|
20
|
-
throw new
|
|
26
|
+
throw new RequiredError(`First item does not exist in collection "${collection}"`, {
|
|
27
|
+
provider: this,
|
|
28
|
+
collection,
|
|
29
|
+
query,
|
|
30
|
+
caller: this.requireFirst,
|
|
31
|
+
});
|
|
21
32
|
return first;
|
|
22
33
|
}
|
|
23
34
|
}
|
|
@@ -26,19 +37,29 @@ export class AsyncProvider {
|
|
|
26
37
|
async requireItem(collection, id) {
|
|
27
38
|
const item = await this.getItem(collection, id);
|
|
28
39
|
if (!item)
|
|
29
|
-
throw new
|
|
40
|
+
throw new RequiredError(`Item does not exist in collection "${collection}"`, {
|
|
41
|
+
provider: this,
|
|
42
|
+
collection,
|
|
43
|
+
id,
|
|
44
|
+
caller: this.requireItem,
|
|
45
|
+
});
|
|
30
46
|
return item;
|
|
31
47
|
}
|
|
32
48
|
async countQuery(collection, query) {
|
|
33
49
|
return countArray(await this.getQuery(collection, query));
|
|
34
50
|
}
|
|
35
51
|
async getFirst(collection, query) {
|
|
36
|
-
return
|
|
52
|
+
return getFirstItem(await this.getQuery(collection, { ...query, $limit: 1 }));
|
|
37
53
|
}
|
|
38
54
|
async requireFirst(collection, query) {
|
|
39
55
|
const first = await this.getFirst(collection, query);
|
|
40
56
|
if (!first)
|
|
41
|
-
throw new
|
|
57
|
+
throw new RequiredError(`First item does not exist in collection "${collection}"`, {
|
|
58
|
+
provider: this,
|
|
59
|
+
collection,
|
|
60
|
+
query,
|
|
61
|
+
caller: this.requireFirst,
|
|
62
|
+
});
|
|
42
63
|
return first;
|
|
43
64
|
}
|
|
44
65
|
}
|
package/db/QueryStore.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { NotFoundError } from "../error/NotFoundError.js";
|
|
1
|
+
import { RequiredError } from "../error/RequiredError.js";
|
|
3
2
|
import { ArrayStore } from "../store/ArrayStore.js";
|
|
4
3
|
import { BooleanStore } from "../store/BooleanStore.js";
|
|
4
|
+
import { getGetter } from "../util/class.js";
|
|
5
5
|
import { NONE } from "../util/constants.js";
|
|
6
6
|
import { getAfterQuery, getLimit } from "../util/query.js";
|
|
7
7
|
import { runSequence } from "../util/sequence.js";
|
|
@@ -21,14 +21,26 @@ 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 RequiredError(`First item does not exist in collection "${this.collection}"`, {
|
|
25
|
+
store: this,
|
|
26
|
+
provider: this.provider,
|
|
27
|
+
collection: this.collection,
|
|
28
|
+
query: this.query,
|
|
29
|
+
caller: getGetter(this, "first"),
|
|
30
|
+
});
|
|
25
31
|
return first;
|
|
26
32
|
}
|
|
27
33
|
/** Get the last item in this store. */
|
|
28
34
|
get last() {
|
|
29
35
|
const last = this.optionalLast;
|
|
30
36
|
if (!last)
|
|
31
|
-
throw new
|
|
37
|
+
throw new RequiredError(`Last item does not exist in collection "${this.collection}"`, {
|
|
38
|
+
store: this,
|
|
39
|
+
provider: this.provider,
|
|
40
|
+
collection: this.collection,
|
|
41
|
+
query: this.query,
|
|
42
|
+
caller: getGetter(this, "first"),
|
|
43
|
+
});
|
|
32
44
|
return last;
|
|
33
45
|
}
|
|
34
46
|
constructor(collection, query, provider, memory) {
|
package/db/ValidationProvider.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ValueError } from "../error/ValueError.js";
|
|
2
2
|
import { Feedback } from "../feedback/Feedback.js";
|
|
3
3
|
import { KEY } from "../schema/KeySchema.js";
|
|
4
4
|
import { updateData } from "../util/update.js";
|
|
@@ -16,12 +16,12 @@ export class ValidationProvider extends ThroughProvider {
|
|
|
16
16
|
return this.schemas[collection];
|
|
17
17
|
}
|
|
18
18
|
getItem(collection, id) {
|
|
19
|
-
return _validateItem(collection, super.getItem(collection, id), this.getSchema(collection));
|
|
19
|
+
return _validateItem(collection, super.getItem(collection, id), this.getSchema(collection), this.getItem);
|
|
20
20
|
}
|
|
21
21
|
async *getItemSequence(collection, id) {
|
|
22
22
|
const schema = this.getSchema(collection);
|
|
23
|
-
for await (const
|
|
24
|
-
yield _validateItem(collection,
|
|
23
|
+
for await (const item of super.getItemSequence(collection, id))
|
|
24
|
+
yield _validateItem(collection, item, schema, this.getItemSequence);
|
|
25
25
|
}
|
|
26
26
|
addItem(collection, data) {
|
|
27
27
|
return super.addItem(collection, validateData(data, this.getSchema(collection).props));
|
|
@@ -40,7 +40,7 @@ export class ValidationProvider extends ThroughProvider {
|
|
|
40
40
|
return super.countQuery(collection, query);
|
|
41
41
|
}
|
|
42
42
|
getQuery(collection, query) {
|
|
43
|
-
return _validateItems(collection, super.getQuery(collection, query), this.getSchema(collection));
|
|
43
|
+
return _validateItems(collection, super.getQuery(collection, query), this.getSchema(collection), this.getQuery);
|
|
44
44
|
}
|
|
45
45
|
setQuery(collection, query, data) {
|
|
46
46
|
super.setQuery(collection, query, this.getSchema(collection).validate(data));
|
|
@@ -54,8 +54,8 @@ export class ValidationProvider extends ThroughProvider {
|
|
|
54
54
|
}
|
|
55
55
|
async *getQuerySequence(collection, query) {
|
|
56
56
|
const schema = this.getSchema(collection);
|
|
57
|
-
for await (const
|
|
58
|
-
yield _validateItems(collection,
|
|
57
|
+
for await (const items of super.getQuerySequence(collection, query))
|
|
58
|
+
yield _validateItems(collection, items, schema, this.getQuerySequence);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
/** Validate an asynchronous source provider (source can have any type because validation guarantees the type). */
|
|
@@ -70,12 +70,12 @@ export class AsyncValidationProvider extends AsyncThroughProvider {
|
|
|
70
70
|
return this.schemas[collection];
|
|
71
71
|
}
|
|
72
72
|
async getItem(collection, id) {
|
|
73
|
-
return _validateItem(collection, await super.getItem(collection, id), this.getSchema(collection));
|
|
73
|
+
return _validateItem(collection, await super.getItem(collection, id), this.getSchema(collection), this.getItem);
|
|
74
74
|
}
|
|
75
75
|
async *getItemSequence(collection, id) {
|
|
76
76
|
const schema = this.getSchema(collection);
|
|
77
|
-
for await (const
|
|
78
|
-
yield _validateItem(collection,
|
|
77
|
+
for await (const item of super.getItemSequence(collection, id))
|
|
78
|
+
yield _validateItem(collection, item, schema, this.getItemSequence);
|
|
79
79
|
}
|
|
80
80
|
addItem(collection, data) {
|
|
81
81
|
return super.addItem(collection, validateData(data, this.getSchema(collection).props));
|
|
@@ -94,12 +94,12 @@ export class AsyncValidationProvider extends AsyncThroughProvider {
|
|
|
94
94
|
return super.countQuery(collection, query);
|
|
95
95
|
}
|
|
96
96
|
async getQuery(collection, query) {
|
|
97
|
-
return _validateItems(collection, await super.getQuery(collection, query), this.getSchema(collection));
|
|
97
|
+
return _validateItems(collection, await super.getQuery(collection, query), this.getSchema(collection), this.getQuery);
|
|
98
98
|
}
|
|
99
99
|
async *getQuerySequence(collection, query) {
|
|
100
100
|
const schema = this.getSchema(collection);
|
|
101
|
-
for await (const
|
|
102
|
-
yield _validateItems(collection,
|
|
101
|
+
for await (const items of super.getQuerySequence(collection, query))
|
|
102
|
+
yield _validateItems(collection, items, schema, this.getQuerySequence);
|
|
103
103
|
}
|
|
104
104
|
setQuery(collection, query, data) {
|
|
105
105
|
return super.setQuery(collection, query, validateData(data, this.getSchema(collection).props));
|
|
@@ -112,39 +112,39 @@ export class AsyncValidationProvider extends AsyncThroughProvider {
|
|
|
112
112
|
return super.deleteQuery(collection, query);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
function _validateItem(collection,
|
|
116
|
-
if (!
|
|
115
|
+
function _validateItem(collection, item, schema, caller) {
|
|
116
|
+
if (!item)
|
|
117
117
|
return undefined;
|
|
118
118
|
try {
|
|
119
|
-
return validateData(
|
|
119
|
+
return validateData(item, { id: KEY, ...schema.props });
|
|
120
120
|
}
|
|
121
121
|
catch (thrown) {
|
|
122
122
|
if (!(thrown instanceof Feedback))
|
|
123
123
|
throw thrown;
|
|
124
|
-
throw new
|
|
124
|
+
throw new ValueError(`Invalid data for "${collection}"`, { collection, item, cause: thrown, caller });
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Validate a set of entities for this query reference.
|
|
129
|
-
* @throws `
|
|
129
|
+
* @throws `ValueError` if one or more items did not validate (conflict because the program is not in an expected state).
|
|
130
130
|
*/
|
|
131
|
-
function _validateItems(collection,
|
|
132
|
-
return Array.from(_yieldValidItems(collection,
|
|
131
|
+
function _validateItems(collection, items, schema, caller) {
|
|
132
|
+
return Array.from(_yieldValidItems(collection, items, { id: KEY, ...schema.props }, caller));
|
|
133
133
|
}
|
|
134
|
-
function* _yieldValidItems(collection,
|
|
134
|
+
function* _yieldValidItems(collection, items, validators, caller) {
|
|
135
135
|
let invalid = false;
|
|
136
|
-
const
|
|
137
|
-
for (const
|
|
136
|
+
const feedbacks = {};
|
|
137
|
+
for (const item of items) {
|
|
138
138
|
try {
|
|
139
|
-
yield validateData(
|
|
139
|
+
yield validateData(item, validators);
|
|
140
140
|
}
|
|
141
141
|
catch (thrown) {
|
|
142
142
|
if (!(thrown instanceof Feedback))
|
|
143
143
|
throw thrown;
|
|
144
144
|
invalid = true;
|
|
145
|
-
|
|
145
|
+
feedbacks[item.id] = thrown;
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
if (invalid)
|
|
149
|
-
throw new
|
|
149
|
+
throw new ValueError(`Invalid data for "${collection}"`, { collection, items, cause: feedbacks, caller });
|
|
150
150
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BaseError, type BaseErrorOptions } from "./BaseError.js";
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when a value is we're asserting something to be true, but it isn't.
|
|
4
|
+
* - Usually thrown from `assertX()` functions, e.g. `assertString()` and `assertNumber()`
|
|
5
|
+
*/
|
|
6
|
+
export declare class AssertionError extends BaseError {
|
|
7
|
+
constructor(message?: string, options?: BaseErrorOptions);
|
|
8
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseError } from "./BaseError.js";
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when a value is we're asserting something to be true, but it isn't.
|
|
4
|
+
* - Usually thrown from `assertX()` functions, e.g. `assertString()` and `assertNumber()`
|
|
5
|
+
*/
|
|
6
|
+
export class AssertionError extends BaseError {
|
|
7
|
+
constructor(message, options) {
|
|
8
|
+
super(message, { caller: AssertionError, ...options });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
AssertionError.prototype.name = "AssertionError";
|
|
12
|
+
AssertionError.prototype.message = "Assertion failed";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AnyConstructor } from "../util/class.js";
|
|
2
|
+
import type { AnyFunction } from "../util/function.js";
|
|
3
|
+
/** Options for `BaseError` that provide additional helpful error functionality. */
|
|
4
|
+
export interface BaseErrorOptions extends ErrorOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Provide additional named contextual data that should be attached to the `Error` instance.
|
|
7
|
+
* - The fields `cause:` and `caller:` are ignored.
|
|
8
|
+
* - `received` and `expected` are recommended for values.
|
|
9
|
+
*/
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
/** Modify the stack to trim off lines after a certain calling function. */
|
|
12
|
+
caller?: AnyFunction | AnyConstructor | undefined;
|
|
13
|
+
}
|
|
14
|
+
/** An error that provides additional helpful functionality. */
|
|
15
|
+
export declare abstract class BaseError extends Error {
|
|
16
|
+
/** Provide additional named contextual data that should be attached to the `Error` instance. */
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
constructor(message?: string, options?: BaseErrorOptions);
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** An error that provides additional helpful functionality. */
|
|
2
|
+
export class BaseError extends Error {
|
|
3
|
+
constructor(message, options) {
|
|
4
|
+
if (options) {
|
|
5
|
+
super(message, options);
|
|
6
|
+
const { cause, caller = BaseError, ...rest } = options;
|
|
7
|
+
for (const [key, value] of Object.entries(rest))
|
|
8
|
+
this[key] = value;
|
|
9
|
+
Error.captureStackTrace(this, caller);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
super(message);
|
|
13
|
+
Error.captureStackTrace(this, BaseError);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
BaseError.prototype.name = "BaseError";
|
|
18
|
+
BaseError.prototype.message = "Unknown error";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BaseError, type BaseErrorOptions } from "./BaseError.js";
|
|
2
|
+
/** Thrown in the event of network issues e.g. the user's internet connection is down, or the server is down. */
|
|
3
|
+
export declare class NetworkError extends BaseError {
|
|
4
|
+
constructor(message?: string, options?: BaseErrorOptions);
|
|
5
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseError } from "./BaseError.js";
|
|
2
|
+
/** Thrown in the event of network issues e.g. the user's internet connection is down, or the server is down. */
|
|
3
|
+
export class NetworkError extends BaseError {
|
|
4
|
+
constructor(message, options) {
|
|
5
|
+
super(message, { caller: NetworkError, ...options });
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
NetworkError.prototype.name = "NetworkError";
|
|
9
|
+
NetworkError.prototype.message = "Network error";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { BaseError, type BaseErrorOptions } from "./BaseError.js";
|
|
2
|
+
/** Options for a `RequestError` */
|
|
3
|
+
interface RequestErrorOptions extends BaseErrorOptions {
|
|
4
|
+
code?: number;
|
|
5
|
+
}
|
|
6
|
+
/** Error thrown when a request isn't well-formed. */
|
|
7
|
+
export declare class RequestError extends BaseError {
|
|
8
|
+
/** The corresponding HTTP status code for this error, in the range `400-499` */
|
|
9
|
+
code: number;
|
|
10
|
+
constructor(message?: string, options?: RequestErrorOptions);
|
|
11
|
+
}
|
|
12
|
+
/** Thrown if an operation failed because the user is not logged in, or the login information is not well-formed. */
|
|
13
|
+
export declare class UnauthorizedError extends RequestError {
|
|
14
|
+
readonly code: number;
|
|
15
|
+
constructor(message?: string, options?: RequestErrorOptions);
|
|
16
|
+
}
|
|
17
|
+
/** Thrown if the requested content is not found. */
|
|
18
|
+
export declare class NotFoundError extends RequestError {
|
|
19
|
+
readonly code = 404;
|
|
20
|
+
constructor(message?: string, options?: RequestErrorOptions);
|
|
21
|
+
}
|
|
22
|
+
/** Error thrown when a request is is valid and well-formed, but its actual data is not. */
|
|
23
|
+
export declare class UnprocessableError extends RequestError {
|
|
24
|
+
readonly code: number;
|
|
25
|
+
constructor(message?: string, options?: RequestErrorOptions);
|
|
26
|
+
}
|
|
27
|
+
/** Thrown if an operation failed because the user is logged in, but does not have sufficient privileges to access this content. */
|
|
28
|
+
export declare class ForbiddenError extends RequestError {
|
|
29
|
+
readonly code: number;
|
|
30
|
+
constructor(message?: string, options?: RequestErrorOptions);
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { BaseError } from "./BaseError.js";
|
|
2
|
+
/** Error thrown when a request isn't well-formed. */
|
|
3
|
+
export class RequestError extends BaseError {
|
|
4
|
+
/** The corresponding HTTP status code for this error, in the range `400-499` */
|
|
5
|
+
code;
|
|
6
|
+
constructor(message = RequestError.prototype.message, options) {
|
|
7
|
+
super(message, { caller: RequestError, ...options });
|
|
8
|
+
this.code = options?.code || 400;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
RequestError.prototype.name = "RequestError";
|
|
12
|
+
RequestError.prototype.message = "Invalid request";
|
|
13
|
+
/** Thrown if an operation failed because the user is not logged in, or the login information is not well-formed. */
|
|
14
|
+
export class UnauthorizedError extends RequestError {
|
|
15
|
+
code = 401;
|
|
16
|
+
constructor(message = UnauthorizedError.prototype.message, options) {
|
|
17
|
+
super(message, { caller: UnauthorizedError, code: 401, ...options });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
UnauthorizedError.prototype.name = "UnauthorizedError";
|
|
21
|
+
UnauthorizedError.prototype.message = "Authorization is required";
|
|
22
|
+
/** Thrown if the requested content is not found. */
|
|
23
|
+
export class NotFoundError extends RequestError {
|
|
24
|
+
code = 404;
|
|
25
|
+
constructor(message = NotFoundError.prototype.message, options) {
|
|
26
|
+
super(message, { caller: NotFoundError, code: 404, ...options });
|
|
27
|
+
Error.captureStackTrace(this, NotFoundError);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
NotFoundError.prototype.name = "NotFoundError";
|
|
31
|
+
NotFoundError.prototype.message = "Cannot find requested content";
|
|
32
|
+
/** Error thrown when a request is is valid and well-formed, but its actual data is not. */
|
|
33
|
+
export class UnprocessableError extends RequestError {
|
|
34
|
+
code = 422;
|
|
35
|
+
constructor(message = UnprocessableError.prototype.message, options) {
|
|
36
|
+
super(message, { caller: UnprocessableError, code: 422, ...options });
|
|
37
|
+
Error.captureStackTrace(this, UnprocessableError);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
UnprocessableError.prototype.name = "UnprocessableError";
|
|
41
|
+
UnprocessableError.prototype.message = "Input data is invalid";
|
|
42
|
+
/** Thrown if an operation failed because the user is logged in, but does not have sufficient privileges to access this content. */
|
|
43
|
+
export class ForbiddenError extends RequestError {
|
|
44
|
+
code = 403;
|
|
45
|
+
constructor(message = ForbiddenError.prototype.message, options) {
|
|
46
|
+
super(message, { caller: ForbiddenError, code: 403, ...options });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
ForbiddenError.prototype.name = "ForbiddenError";
|
|
50
|
+
ForbiddenError.prototype.message = "Insufficient privileges to access this content";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BaseError, type BaseErrorOptions } from "./BaseError.js";
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when something is required but not supplied.
|
|
4
|
+
* - Usually thrown from `requireX()` functions, e.g. `requireString()` and `requireNumber()`
|
|
5
|
+
*/
|
|
6
|
+
export declare class RequiredError extends BaseError {
|
|
7
|
+
constructor(message?: string, options?: BaseErrorOptions);
|
|
8
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseError } from "./BaseError.js";
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when something is required but not supplied.
|
|
4
|
+
* - Usually thrown from `requireX()` functions, e.g. `requireString()` and `requireNumber()`
|
|
5
|
+
*/
|
|
6
|
+
export class RequiredError extends BaseError {
|
|
7
|
+
constructor(message, options) {
|
|
8
|
+
super(message, { caller: RequiredError, ...options });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
RequiredError.prototype.name = "RequiredError";
|
|
12
|
+
RequiredError.prototype.message = "Value is required";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseError } from "./BaseError.js";
|
|
2
|
+
/** Thrown when something is wrong or unexpected. */
|
|
3
|
+
export class UnexpectedError extends BaseError {
|
|
4
|
+
constructor(message, options) {
|
|
5
|
+
super(message, { caller: UnexpectedError, ...options });
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
UnexpectedError.prototype.name = "UnexpectedError";
|
|
9
|
+
UnexpectedError.prototype.message = "Unexpected error";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BaseError, type BaseErrorOptions } from "./BaseError.js";
|
|
2
|
+
/** Error thrown when functionality is called but is not implemented by an interface. */
|
|
3
|
+
export declare class UnimplementedError extends BaseError {
|
|
4
|
+
constructor(message?: string, options?: BaseErrorOptions);
|
|
5
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseError } from "./BaseError.js";
|
|
2
|
+
/** Error thrown when functionality is called but is not implemented by an interface. */
|
|
3
|
+
export class UnimplementedError extends BaseError {
|
|
4
|
+
constructor(message, options) {
|
|
5
|
+
super(message, { caller: UnimplementedError, ...options });
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
UnimplementedError.prototype.name = "UnimplementedError";
|
|
9
|
+
UnimplementedError.prototype.message = "Not implemented";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseError } from "./BaseError.js";
|
|
2
|
+
/** Thrown when a value is wrong or unexpected. */
|
|
3
|
+
export class ValueError extends BaseError {
|
|
4
|
+
constructor(message, options) {
|
|
5
|
+
super(message, { caller: ValueError, ...options });
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
ValueError.prototype.name = "ValueError";
|
|
9
|
+
ValueError.prototype.message = "Invalid value";
|
package/error/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
6
|
-
export * from "./
|
|
7
|
-
export * from "./
|
|
8
|
-
export * from "./
|
|
1
|
+
export * from "./BaseError.js";
|
|
2
|
+
export * from "./AssertionError.js";
|
|
3
|
+
export * from "./NetworkError.js";
|
|
4
|
+
export * from "./RequestError.js";
|
|
5
|
+
export * from "./RequiredError.js";
|
|
6
|
+
export * from "./UnexpectedError.js";
|
|
7
|
+
export * from "./UnimplementedError.js";
|
|
8
|
+
export * from "./ValueError.js";
|
package/error/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
6
|
-
export * from "./
|
|
7
|
-
export * from "./
|
|
8
|
-
export * from "./
|
|
1
|
+
export * from "./BaseError.js";
|
|
2
|
+
export * from "./AssertionError.js";
|
|
3
|
+
export * from "./NetworkError.js";
|
|
4
|
+
export * from "./RequestError.js";
|
|
5
|
+
export * from "./RequiredError.js";
|
|
6
|
+
export * from "./UnexpectedError.js";
|
|
7
|
+
export * from "./UnimplementedError.js";
|
|
8
|
+
export * from "./ValueError.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 { UnimplementedError } from "../../error/UnimplementedError.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 UnimplementedError("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 UnimplementedError("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));
|