shelving 1.116.2 → 1.117.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.
Files changed (58) hide show
  1. package/api/Resource.js +2 -2
  2. package/db/ValidationProvider.js +3 -3
  3. package/error/AssertionError.d.ts +6 -11
  4. package/error/AssertionError.js +6 -19
  5. package/error/ConnectionError.d.ts +6 -3
  6. package/error/ConnectionError.js +7 -3
  7. package/error/EnhancedError.d.ts +9 -0
  8. package/error/EnhancedError.js +15 -0
  9. package/error/PermissionError.d.ts +4 -1
  10. package/error/PermissionError.js +6 -1
  11. package/error/RequiredError.d.ts +5 -3
  12. package/error/RequiredError.js +7 -3
  13. package/error/UnimplementedError.d.ts +6 -0
  14. package/error/UnimplementedError.js +9 -0
  15. package/error/ValueError.d.ts +6 -0
  16. package/error/ValueError.js +9 -0
  17. package/error/index.d.ts +2 -3
  18. package/error/index.js +2 -3
  19. package/firestore/lite/FirestoreLiteProvider.js +3 -3
  20. package/iterate/InspectGenerator.js +4 -4
  21. package/package.json +1 -1
  22. package/react/createCacheContext.js +2 -2
  23. package/sequence/InspectSequence.js +4 -4
  24. package/util/assert.d.ts +0 -2
  25. package/util/assert.js +2 -7
  26. package/util/boolean.js +6 -6
  27. package/util/color.js +3 -3
  28. package/util/date.d.ts +3 -3
  29. package/util/date.js +6 -6
  30. package/util/dictionary.d.ts +8 -4
  31. package/util/dictionary.js +18 -6
  32. package/util/duration.d.ts +7 -14
  33. package/util/duration.js +19 -22
  34. package/util/error.d.ts +13 -0
  35. package/util/error.js +19 -0
  36. package/util/function.js +2 -2
  37. package/util/number.d.ts +2 -2
  38. package/util/number.js +11 -8
  39. package/util/object.d.ts +1 -1
  40. package/util/object.js +1 -1
  41. package/util/optional.js +1 -1
  42. package/util/regexp.js +2 -2
  43. package/util/string.js +2 -1
  44. package/util/time.d.ts +1 -1
  45. package/util/time.js +3 -3
  46. package/util/undefined.js +2 -2
  47. package/util/units.js +3 -3
  48. package/util/url.d.ts +1 -1
  49. package/util/url.js +4 -4
  50. package/util/validate.js +2 -2
  51. package/error/ConditionError.d.ts +0 -7
  52. package/error/ConditionError.js +0 -8
  53. package/error/UnsupportedError.d.ts +0 -4
  54. package/error/UnsupportedError.js +0 -5
  55. package/error/ValidationError.d.ts +0 -4
  56. package/error/ValidationError.js +0 -5
  57. package/firestore/util/error.d.ts +0 -2
  58. package/firestore/util/error.js +0 -19
package/api/Resource.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ValidationError } from "../error/ValidationError.js";
1
+ import { ValueError } from "../error/ValueError.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 ValidationError(`Invalid result for resource`, thrown);
44
+ throw new ValueError(`Invalid result for resource`, thrown);
45
45
  throw thrown;
46
46
  }
47
47
  }
@@ -1,4 +1,4 @@
1
- import { ValidationError } from "../error/ValidationError.js";
1
+ import { ValueError } from "../error/ValueError.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";
@@ -116,7 +116,7 @@ function _validateItem(collection, unsafeEntity, schema) {
116
116
  catch (thrown) {
117
117
  if (!(thrown instanceof Feedback))
118
118
  throw thrown;
119
- throw new ValidationError(`Invalid data for "${collection}"`, thrown.message);
119
+ throw new ValueError(`Invalid data for "${collection}"`, thrown.message);
120
120
  }
121
121
  }
122
122
  /** Validate a set of entities for this query reference. */
@@ -138,5 +138,5 @@ function* _yieldValidItems(collection, unsafeEntities, schema) {
138
138
  }
139
139
  }
140
140
  if (invalid)
141
- throw new ValidationError(`Invalid data for "${collection}"`, messages);
141
+ throw new ValueError(`Invalid data for "${collection}"`, messages);
142
142
  }
@@ -1,12 +1,7 @@
1
- /**
2
- * Thrown if the program receives a value it didn't expect.
3
- *
4
- * @param message Message that explains why the thing happened.
5
- * @param received The value that made the assertion fail.
6
- * @param expected The value that made the assertion fail.
7
- */
8
- export declare class AssertionError extends Error {
9
- readonly received: unknown;
10
- readonly expected: unknown;
11
- constructor(message?: string, ...receivedExpected: readonly [received?: unknown, expected?: unknown]);
1
+ import type { ErrorCode } from "../util/error.js";
2
+ import { EnhancedError } from "./EnhancedError.js";
3
+ /** Thrown if the is in a state . */
4
+ export declare class AssertionError extends EnhancedError {
5
+ readonly code: ErrorCode;
6
+ constructor(message?: string, context?: unknown);
12
7
  }
@@ -1,22 +1,9 @@
1
- import { debug, indent } from "../util/debug.js";
2
- /**
3
- * Thrown if the program receives a value it didn't expect.
4
- *
5
- * @param message Message that explains why the thing happened.
6
- * @param received The value that made the assertion fail.
7
- * @param expected The value that made the assertion fail.
8
- */
9
- export class AssertionError extends Error {
10
- received;
11
- expected;
12
- constructor(message = "Failed assertion", ...receivedExpected) {
13
- super(receivedExpected.length >= 2 //
14
- ? `${message}\nReceived:${indent(debug(receivedExpected[0]))}\nExpected:${indent(debug(receivedExpected[0]))}`
15
- : receivedExpected.length >= 1
16
- ? `${message}\nReceived:${indent(debug(receivedExpected[0]))}`
17
- : message);
18
- this.received = receivedExpected[0];
19
- this.expected = receivedExpected[1];
1
+ import { EnhancedError } from "./EnhancedError.js";
2
+ /** Thrown if the is in a state . */
3
+ export class AssertionError extends EnhancedError {
4
+ code = "failed-precondition";
5
+ constructor(message = "Failed precondition", context) {
6
+ super(message, context);
20
7
  }
21
8
  }
22
9
  AssertionError.prototype.name = "AssertionError";
@@ -1,4 +1,7 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /** Thrown if a user's internet connection fails. */
3
- export declare class ConnectionError extends AssertionError {
1
+ import type { ErrorCode } from "../util/error.js";
2
+ import { EnhancedError } from "./EnhancedError.js";
3
+ /** Thrown if e.g. a user's internet connection fails. */
4
+ export declare class ConnectionError extends EnhancedError {
5
+ readonly code: ErrorCode;
6
+ constructor(message?: string, context?: unknown);
4
7
  }
@@ -1,5 +1,9 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /** Thrown if a user's internet connection fails. */
3
- export class ConnectionError extends AssertionError {
1
+ import { EnhancedError } from "./EnhancedError.js";
2
+ /** Thrown if e.g. a user's internet connection fails. */
3
+ export class ConnectionError extends EnhancedError {
4
+ code = "unavailable";
5
+ constructor(message = "Connection error", context) {
6
+ super(message, context);
7
+ }
4
8
  }
5
9
  ConnectionError.prototype.name = "ConnectionError";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Error with a `.context` field to provide information about what went wrong.
3
+ * - Context is appended to `.message` in the format `message: debuggedContext`
4
+ * - Context is converted to a string using `debug()`
5
+ */
6
+ export declare class EnhancedError extends global.Error {
7
+ readonly context: unknown;
8
+ constructor(message: string, context?: unknown);
9
+ }
@@ -0,0 +1,15 @@
1
+ import { debug } from "../util/debug.js";
2
+ /**
3
+ * Error with a `.context` field to provide information about what went wrong.
4
+ * - Context is appended to `.message` in the format `message: debuggedContext`
5
+ * - Context is converted to a string using `debug()`
6
+ */
7
+ export class EnhancedError extends global.Error {
8
+ context;
9
+ constructor(message, context) {
10
+ const debugged = context !== undefined ? debug(context, 2) : "";
11
+ super(debugged.length ? `${message}: ${debugged}` : message);
12
+ this.context = context;
13
+ }
14
+ }
15
+ EnhancedError.prototype.name = "EnhancedError";
@@ -1,3 +1,6 @@
1
+ import { EnhancedError } from "./EnhancedError.js";
1
2
  /** Thrown if an operation failed due to permissions. */
2
- export declare class PermissionError extends Error {
3
+ export declare class PermissionError extends EnhancedError {
4
+ readonly code = "permission-denied";
5
+ constructor(message?: string, context?: unknown);
3
6
  }
@@ -1,4 +1,9 @@
1
+ import { EnhancedError } from "./EnhancedError.js";
1
2
  /** Thrown if an operation failed due to permissions. */
2
- export class PermissionError extends Error {
3
+ export class PermissionError extends EnhancedError {
4
+ code = "permission-denied";
5
+ constructor(message = "Permission denied", context) {
6
+ super(message, context);
7
+ }
3
8
  }
4
9
  PermissionError.prototype.name = "PermissionError";
@@ -1,4 +1,6 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /** Thrown if a value is required but wasn't provided. */
3
- export declare class RequiredError extends AssertionError {
1
+ import { EnhancedError } from "./EnhancedError.js";
2
+ /** Thrown if e.g. a value is required but wasn't provided. */
3
+ export declare class RequiredError extends EnhancedError {
4
+ readonly code = "not-found";
5
+ constructor(message?: string, context?: unknown);
4
6
  }
@@ -1,5 +1,9 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /** Thrown if a value is required but wasn't provided. */
3
- export class RequiredError extends AssertionError {
1
+ import { EnhancedError } from "./EnhancedError.js";
2
+ /** Thrown if e.g. a value is required but wasn't provided. */
3
+ export class RequiredError extends EnhancedError {
4
+ code = "not-found";
5
+ constructor(message = "Value is required", context) {
6
+ super(message, context);
7
+ }
4
8
  }
5
9
  RequiredError.prototype.name = "RequiredError";
@@ -0,0 +1,6 @@
1
+ import { EnhancedError } from "./EnhancedError.js";
2
+ /** Error thrown when functionality is called but is not implemented by an interface. */
3
+ export declare class UnimplementedError extends EnhancedError {
4
+ readonly code = "unimplemented";
5
+ constructor(message?: string, value?: unknown);
6
+ }
@@ -0,0 +1,9 @@
1
+ import { EnhancedError } from "./EnhancedError.js";
2
+ /** Error thrown when functionality is called but is not implemented by an interface. */
3
+ export class UnimplementedError extends EnhancedError {
4
+ code = "unimplemented";
5
+ constructor(message = "Not implemented", value) {
6
+ super(message, value);
7
+ }
8
+ }
9
+ UnimplementedError.prototype.name = "UnimplementedError";
@@ -0,0 +1,6 @@
1
+ import { EnhancedError } from "./EnhancedError.js";
2
+ /** Error thrown when a value isn't valid. */
3
+ export declare class ValueError extends EnhancedError {
4
+ readonly code = "invalid-argument";
5
+ constructor(message?: string, context?: unknown);
6
+ }
@@ -0,0 +1,9 @@
1
+ import { EnhancedError } from "./EnhancedError.js";
2
+ /** Error thrown when a value isn't valid. */
3
+ export class ValueError extends EnhancedError {
4
+ code = "invalid-argument";
5
+ constructor(message = "Invalid value", context) {
6
+ super(message, context);
7
+ }
8
+ }
9
+ ValueError.prototype.name = "ValidationError";
package/error/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from "./AssertionError.js";
2
- export * from "./ConditionError.js";
3
2
  export * from "./ConnectionError.js";
4
3
  export * from "./PermissionError.js";
5
4
  export * from "./RequiredError.js";
6
- export * from "./UnsupportedError.js";
7
- export * from "./ValidationError.js";
5
+ export * from "./UnimplementedError.js";
6
+ export * from "./ValueError.js";
package/error/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from "./AssertionError.js";
2
- export * from "./ConditionError.js";
3
2
  export * from "./ConnectionError.js";
4
3
  export * from "./PermissionError.js";
5
4
  export * from "./RequiredError.js";
6
- export * from "./UnsupportedError.js";
7
- export * from "./ValidationError.js";
5
+ export * from "./UnimplementedError.js";
6
+ export * from "./ValueError.js";
@@ -1,5 +1,5 @@
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
- import { UnsupportedError } from "../../error/UnsupportedError.js";
2
+ import { UnimplementedError } from "../../error/UnimplementedError.js";
3
3
  import { getItem } from "../../util/item.js";
4
4
  import { getObject } from "../../util/object.js";
5
5
  import { getFilters, getLimit, getOrders } from "../../util/query.js";
@@ -72,7 +72,7 @@ export class FirestoreLiteProvider {
72
72
  return _getOptionalItem(snapshot);
73
73
  }
74
74
  getItemSequence() {
75
- throw new UnsupportedError("FirestoreLiteProvider does not support realtime subscriptions");
75
+ throw new UnimplementedError("FirestoreLiteProvider does not support realtime subscriptions");
76
76
  }
77
77
  async addItem(c, data) {
78
78
  const reference = await addDoc(collection(this._firestore, c), data);
@@ -96,7 +96,7 @@ export class FirestoreLiteProvider {
96
96
  return snapshot.docs.map(_getItem);
97
97
  }
98
98
  getQuerySequence() {
99
- throw new UnsupportedError("FirestoreLiteProvider does not support realtime subscriptions");
99
+ throw new UnimplementedError("FirestoreLiteProvider does not support realtime subscriptions");
100
100
  }
101
101
  async setQuery(c, q, data) {
102
102
  const snapshot = await getDocs(_getQuery(this._firestore, c, q));
@@ -1,4 +1,4 @@
1
- import { ConditionError } from "../error/ConditionError.js";
1
+ import { AssertionError } from "../error/AssertionError.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 ConditionError("Iteration not started");
23
+ throw new AssertionError("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 ConditionError("Iteration not started");
30
+ throw new AssertionError("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 ConditionError("Iteration not done");
37
+ throw new AssertionError("Iteration not done");
38
38
  return this._returned;
39
39
  }
40
40
  _returned = _NOVALUE;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "state-management",
12
12
  "query-builder"
13
13
  ],
14
- "version": "1.116.2",
14
+ "version": "1.117.0",
15
15
  "repository": "https://github.com/dhoulb/shelving",
16
16
  "author": "Dave Houlbrooke <dave@shax.com>",
17
17
  "license": "0BSD",
@@ -1,5 +1,5 @@
1
1
  import { createContext, createElement, useContext, useRef } from "react";
2
- import { ConditionError } from "../error/ConditionError.js";
2
+ import { AssertionError } from "../error/AssertionError.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 ConditionError("useCache() must be used inside <Cache>");
13
+ throw new AssertionError("useCache() must be used inside <Cache>");
14
14
  return cache;
15
15
  },
16
16
  CacheContext({ children }) {
@@ -1,4 +1,4 @@
1
- import { ConditionError } from "../error/ConditionError.js";
1
+ import { AssertionError } from "../error/AssertionError.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 ConditionError("Iteration not started");
23
+ throw new AssertionError("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 ConditionError("Iteration not started");
30
+ throw new AssertionError("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 ConditionError("Iteration not done");
37
+ throw new AssertionError("Iteration not done");
38
38
  return this._returned;
39
39
  }
40
40
  _returned = _NOVALUE;
package/util/assert.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- /** Assert a boolean condition is true. */
2
- export declare function assert(condition: unknown, ...receivedExpected: [received?: unknown, expected?: unknown]): asserts condition;
3
1
  /** Assert two values are equal. */
4
2
  export declare function assertEqual<T>(left: unknown, right: T): asserts left is T;
5
3
  /** Assert two values are equal. */
package/util/assert.js CHANGED
@@ -1,16 +1,11 @@
1
1
  import { AssertionError } from "../error/AssertionError.js";
2
- /** Assert a boolean condition is true. */
3
- export function assert(condition, ...receivedExpected) {
4
- if (!condition)
5
- throw new AssertionError(`Must assert`, ...receivedExpected);
6
- }
7
2
  /** Assert two values are equal. */
8
3
  export function assertEqual(left, right) {
9
4
  if (left !== right)
10
- throw new AssertionError(`Must be equal`, left, right);
5
+ throw new AssertionError(`Must be equal`, { left, right });
11
6
  }
12
7
  /** Assert two values are equal. */
13
8
  export function assertNot(left, right) {
14
9
  if (left === right)
15
- throw new AssertionError(`Must not be equal`, left, right);
10
+ throw new AssertionError(`Must not be equal`, { left, right });
16
11
  }
package/util/boolean.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.js";
2
2
  /** Is a value a boolean? */
3
3
  export const isBoolean = (value) => typeof value === "boolean";
4
4
  /** Is a value true? */
@@ -12,25 +12,25 @@ export const isFalsey = (value) => !value;
12
12
  /** Assert that a value is a boolean. */
13
13
  export function assertBoolean(value) {
14
14
  if (typeof value !== "boolean")
15
- throw new AssertionError(`Must be boolean`, value);
15
+ throw new ValueError(`Must be boolean`, value);
16
16
  }
17
17
  /** Assert that a value is true. */
18
18
  export function assertTrue(value) {
19
19
  if (value !== true)
20
- throw new AssertionError(`Must be true`, value);
20
+ throw new ValueError(`Must be true`, value);
21
21
  }
22
22
  /** Assert that a value is false. */
23
23
  export function assertFalse(value) {
24
24
  if (value !== false)
25
- throw new AssertionError(`Must be false`, value);
25
+ throw new ValueError(`Must be false`, value);
26
26
  }
27
27
  /** Assert that a value is truthy. */
28
28
  export function assertTruthy(value) {
29
29
  if (!value)
30
- throw new AssertionError(`Must be truthy`, value);
30
+ throw new ValueError(`Must be truthy`, value);
31
31
  }
32
32
  /** Assert that a value is falsy. */
33
33
  export function assertFalsy(value) {
34
34
  if (value)
35
- throw new AssertionError(`Must be falsy`, value);
35
+ throw new ValueError(`Must be falsy`, value);
36
36
  }
package/util/color.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.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.
@@ -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 AssertionError("Invalid color", value);
68
+ throw new ValueError("Invalid color", value);
69
69
  }
70
70
  /** Convert a possible color to a `Color` instance or `undefined` */
71
71
  export function getOptionalColor(possible) {
@@ -75,6 +75,6 @@ export function getOptionalColor(possible) {
75
75
  export function getColor(possible) {
76
76
  const color = getOptionalColor(possible);
77
77
  if (!color)
78
- throw new AssertionError("Invalid color", possible);
78
+ throw new ValueError("Invalid color", possible);
79
79
  return color;
80
80
  }
package/util/date.d.ts CHANGED
@@ -24,15 +24,15 @@ export declare function assertDate(value: unknown): asserts value is Date;
24
24
  * @returns `Date` instance if the value could be converted to a valid date, and `null` if not.
25
25
  */
26
26
  export declare function getOptionalDate(possible?: unknown): Date | undefined;
27
- /** Convert a possible date to a `Date` instance, or throw `AssertionError` if it couldn't be converted. */
27
+ /** Convert a possible date to a `Date` instance, or throw `ValueError` if it couldn't be converted. */
28
28
  export declare function getDate(possible?: PossibleDate): Date;
29
29
  /** Convert an unknown value to a timestamp (milliseconds past Unix epoch), or `undefined` if it couldn't be converted. */
30
30
  export declare function getOptionalTimestamp(possible: unknown): number | undefined;
31
- /** Convert a possible date to a timestamp (milliseconds past Unix epoch), or throw `AssertionError` if it couldn't be converted. */
31
+ /** Convert a possible date to a timestamp (milliseconds past Unix epoch), or throw `ValueError` if it couldn't be converted. */
32
32
  export declare function getTimestamp(possible?: PossibleDate): number;
33
33
  /** Convert an unknown value to a YMD date string like "2015-09-12", or `undefined` if it couldn't be converted. */
34
34
  export declare function getOptionalYMD(possible: unknown): string | undefined;
35
- /** Convert a `Date` instance to a YMD string like "2015-09-12", or throw `AssertionError` if it couldn't be converted. */
35
+ /** Convert a `Date` instance to a YMD string like "2015-09-12", or throw `ValueError` if it couldn't be converted. */
36
36
  export declare function getYMD(possible?: PossibleDate): string;
37
37
  /** List of day-of-week strings. */
38
38
  export declare const DAYS: readonly ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
package/util/date.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.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 AssertionError(`Must be date`, value);
9
+ throw new ValueError(`Must be date`, value);
10
10
  }
11
11
  /**
12
12
  * Convert an unknown value to a valid `Date` instance, or `null` if it couldn't be converted.
@@ -46,18 +46,18 @@ export function getOptionalDate(possible = "now") {
46
46
  return date;
47
47
  }
48
48
  }
49
- /** Convert a possible date to a `Date` instance, or throw `AssertionError` if it couldn't be converted. */
49
+ /** Convert a possible date to a `Date` instance, or throw `ValueError` if it couldn't be converted. */
50
50
  export function getDate(possible) {
51
51
  const date = getOptionalDate(possible);
52
52
  if (!date)
53
- throw new AssertionError(`Must be date`, possible);
53
+ throw new ValueError(`Must be 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. */
57
57
  export function getOptionalTimestamp(possible) {
58
58
  return getOptionalDate(possible)?.getTime();
59
59
  }
60
- /** Convert a possible date to a timestamp (milliseconds past Unix epoch), or throw `AssertionError` if it couldn't be converted. */
60
+ /** Convert a possible date to a timestamp (milliseconds past Unix epoch), or throw `ValueError` if it couldn't be converted. */
61
61
  export function getTimestamp(possible) {
62
62
  return getDate(possible).getTime();
63
63
  }
@@ -67,7 +67,7 @@ export function getOptionalYMD(possible) {
67
67
  if (date)
68
68
  return _ymd(date);
69
69
  }
70
- /** Convert a `Date` instance to a YMD string like "2015-09-12", or throw `AssertionError` if it couldn't be converted. */
70
+ /** Convert a `Date` instance to a YMD string like "2015-09-12", or throw `ValueError` if it couldn't be converted. */
71
71
  export function getYMD(possible) {
72
72
  return _ymd(getDate(possible));
73
73
  }
@@ -16,15 +16,19 @@ export type PossibleDictionary<T> = ImmutableDictionary<T> | Iterable<Dictionary
16
16
  export declare const isDictionary: (value: unknown) => value is ImmutableDictionary<unknown>;
17
17
  /** Assert that an unknown value is a dictionary object */
18
18
  export declare function assertDictionary(value: unknown): asserts value is ImmutableDictionary;
19
- /** Is an unknown value the key for an own prop of a dictionary. */
20
- export declare const isDictionaryItem: <T>(obj: ImmutableDictionary<T>, key: unknown) => key is string;
21
- /** Assert that an unknown value is the key for an own prop of a dictionary. */
22
- export declare function assertDictionaryItem<T>(obj: ImmutableDictionary<T>, key: unknown): asserts key is string;
23
19
  /** turn a possible dictionary into a dictionary. */
24
20
  export declare function getDictionary<T>(obj: PossibleDictionary<T>): ImmutableDictionary<T>;
25
21
  /** Turn a dictionary object into a set of props. */
26
22
  export declare function getDictionaryItems<T>(obj: ImmutableDictionary<T>): readonly DictionaryItem<T>[];
27
23
  export declare function getDictionaryItems<T>(obj: PossibleDictionary<T>): Iterable<DictionaryItem<T>>;
24
+ /** Is an unknown value the key for an own prop of a dictionary. */
25
+ export declare const isDictionaryItem: <T>(obj: ImmutableDictionary<T>, key: unknown) => key is string;
26
+ /** Assert that an unknown value is the key for an own prop of a dictionary. */
27
+ export declare function assertDictionaryItem<T>(obj: ImmutableDictionary<T>, key: unknown): asserts key is string;
28
+ /** Get an item in a map or throw an error if it doesn't exist. */
29
+ export declare function getDictionaryItem<T>(obj: ImmutableDictionary<T>, key: string): T;
30
+ /** Get an item in a map or `undefined` if it doesn't exist. */
31
+ export declare function getOptionalDictionaryItem<T>(obj: ImmutableDictionary<T>, key: string): T | undefined;
28
32
  /** Set a prop on a dictionary object (immutably) and return a new object including that prop. */
29
33
  export declare const withDictionaryItem: <T>(input: ImmutableDictionary<T>, key: string, value: T) => ImmutableDictionary<T>;
30
34
  /** Set several props on a dictionary object (immutably) and return a new object including those props. */
@@ -1,4 +1,6 @@
1
1
  import { AssertionError } from "../error/AssertionError.js";
2
+ import { RequiredError } from "../error/RequiredError.js";
3
+ import { ValueError } from "../error/ValueError.js";
2
4
  import { isIterable } from "./iterate.js";
3
5
  import { deleteProps, isPlainObject, omitProps, pickProps, setProp, setProps, withProp, withProps } from "./object.js";
4
6
  /** Is an unknown value a dictionary object? */
@@ -6,7 +8,14 @@ export const isDictionary = (value) => isPlainObject(value);
6
8
  /** Assert that an unknown value is a dictionary object */
7
9
  export function assertDictionary(value) {
8
10
  if (!isDictionary(value))
9
- throw new AssertionError("Must be dictionary", value);
11
+ throw new ValueError("Must be dictionary", value);
12
+ }
13
+ /** turn a possible dictionary into a dictionary. */
14
+ export function getDictionary(obj) {
15
+ return isIterable(obj) ? Object.fromEntries(obj) : obj;
16
+ }
17
+ export function getDictionaryItems(obj) {
18
+ return isIterable(obj) ? obj : Object.entries(obj);
10
19
  }
11
20
  /** Is an unknown value the key for an own prop of a dictionary. */
12
21
  export const isDictionaryItem = (obj, key) => typeof key === "string" && Object.hasOwn(obj, key);
@@ -15,12 +24,15 @@ export function assertDictionaryItem(obj, key) {
15
24
  if (!isDictionaryItem(obj, key))
16
25
  throw new AssertionError("Must be dictionary item", key);
17
26
  }
18
- /** turn a possible dictionary into a dictionary. */
19
- export function getDictionary(obj) {
20
- return isIterable(obj) ? Object.fromEntries(obj) : obj;
27
+ /** Get an item in a map or throw an error if it doesn't exist. */
28
+ export function getDictionaryItem(obj, key) {
29
+ if (!Object.hasOwn(obj, key))
30
+ throw new RequiredError(`Dictionary item is required`);
31
+ return obj[key];
21
32
  }
22
- export function getDictionaryItems(obj) {
23
- return isIterable(obj) ? obj : Object.entries(obj);
33
+ /** Get an item in a map or `undefined` if it doesn't exist. */
34
+ export function getOptionalDictionaryItem(obj, key) {
35
+ return obj[key];
24
36
  }
25
37
  /** Set a prop on a dictionary object (immutably) and return a new object including that prop. */
26
38
  export const withDictionaryItem = withProp;
@@ -1,17 +1,10 @@
1
- import type { PossibleDate } from "./date.js";
2
- /** Format a full format of a duration of time using the most reasonable units e.g. `5 years` or `1 week` or `4 minutes` or `12 milliseconds`. */
3
- export declare function pluralizeDuration(ms: number): string;
1
+ import { type PossibleDate } from "./date.js";
2
+ import { type NumberOptions } from "./number.js";
4
3
  /** Format a description of a duration of time using the most reasonable units e.g. `5y` or `4m` or `12ms`. */
5
- export declare function formatDuration(ms: number): string;
6
- /** Full when a date happens/happened, e.g. `in 10 days` or `2 hours ago` */
7
- export declare const pluralizeWhen: (target: PossibleDate, current?: PossibleDate) => string;
8
- /** Compact when a date happens/happened, e.g. `in 10d` or `2h ago` or `in 1w` */
9
- export declare const formatWhen: (target: PossibleDate, current?: PossibleDate) => string;
10
- /** Full when a date happens, e.g. `10 days` or `2 hours` or `-1 week` */
11
- export declare const pluralizeUntil: (target: PossibleDate, current?: PossibleDate) => string;
4
+ export declare function formatDuration(ms: number, options?: NumberOptions): string;
5
+ /** Compact when a date happens/happened, e.g. `in 10d` or `2h ago` or `in 1w` or `just now` */
6
+ export declare function formatWhen(target: PossibleDate, current?: PossibleDate, options?: NumberOptions): string;
12
7
  /** Compact when a date happens, e.g. `10d` or `2h` or `-1w` */
13
- export declare const formatUntil: (target: PossibleDate, current?: PossibleDate) => string;
14
- /** Full when a date happened, e.g. `10 days` or `2 hours` or `-1 week` */
15
- export declare const pluralizeAgo: (target: PossibleDate, current?: PossibleDate) => string;
8
+ export declare function formatUntil(target: PossibleDate, current?: PossibleDate, options?: NumberOptions): string;
16
9
  /** Compact when a date will happen, e.g. `10d` or `2h` or `-1w` */
17
- export declare const formatAgo: (target: PossibleDate, current?: PossibleDate) => string;
10
+ export declare function formatAgo(target: PossibleDate, current?: PossibleDate, options?: NumberOptions): string;
package/util/duration.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { DAY, HOUR, MONTH, SECOND, WEEK } from "./constants.js";
2
2
  import { getDuration } from "./date.js";
3
+ import { formatNumber } from "./number.js";
3
4
  import { TIME_UNITS } from "./units.js";
4
5
  /** Get an appropriate time unit based on an amount in milliseconds. */
5
6
  function _getTimeUnit(ms) {
@@ -21,33 +22,29 @@ function _getTimeUnit(ms) {
21
22
  return TIME_UNITS.getUnit("millisecond");
22
23
  }
23
24
  /** Default number options for duration (no decimal places and rounding down). */
24
- const NUMBER_OPTIONS = { maximumFractionDigits: 0, roundingMode: "trunc" };
25
- /** Format a full format of a duration of time using the most reasonable units e.g. `5 years` or `1 week` or `4 minutes` or `12 milliseconds`. */
26
- export function pluralizeDuration(ms) {
27
- const unit = _getTimeUnit(ms);
28
- return unit.pluralize(unit.from(ms), NUMBER_OPTIONS);
29
- }
25
+ const DURATION_OPTIONS = {
26
+ style: "unit",
27
+ unitDisplay: "narrow",
28
+ maximumFractionDigits: 0,
29
+ roundingMode: "trunc",
30
+ roundingPriority: "lessPrecision",
31
+ };
30
32
  /** Format a description of a duration of time using the most reasonable units e.g. `5y` or `4m` or `12ms`. */
31
- export function formatDuration(ms) {
33
+ export function formatDuration(ms, options) {
32
34
  const unit = _getTimeUnit(ms);
33
- return unit.format(unit.from(ms), NUMBER_OPTIONS);
35
+ return formatNumber(unit.from(ms), { ...DURATION_OPTIONS, ...options, unit: unit.key });
34
36
  }
35
- /** format when a data happens/happened. */
36
- function _formatWhen(formatter, target, current) {
37
+ /** Compact when a date happens/happened, e.g. `in 10d` or `2h ago` or `in 1w` or `just now` */
38
+ export function formatWhen(target, current, options) {
37
39
  const ms = getDuration(target, current);
38
40
  const abs = Math.abs(ms);
39
- const duration = formatter(ms);
40
- return abs < 10 * SECOND ? "just now" : ms > 0 ? `in ${duration}` : `${duration} ago`;
41
+ return abs < 30 * SECOND ? "just now" : ms > 0 ? `in ${formatDuration(abs, options)}` : `${formatDuration(abs, options)} ago`;
41
42
  }
42
- /** Full when a date happens/happened, e.g. `in 10 days` or `2 hours ago` */
43
- export const pluralizeWhen = (target, current) => _formatWhen(pluralizeDuration, target, current);
44
- /** Compact when a date happens/happened, e.g. `in 10d` or `2h ago` or `in 1w` */
45
- export const formatWhen = (target, current) => _formatWhen(formatDuration, target, current);
46
- /** Full when a date happens, e.g. `10 days` or `2 hours` or `-1 week` */
47
- export const pluralizeUntil = (target, current) => pluralizeDuration(getDuration(target, current));
48
43
  /** Compact when a date happens, e.g. `10d` or `2h` or `-1w` */
49
- export const formatUntil = (target, current) => formatDuration(getDuration(target, current));
50
- /** Full when a date happened, e.g. `10 days` or `2 hours` or `-1 week` */
51
- export const pluralizeAgo = (target, current) => pluralizeDuration(getDuration(current, target));
44
+ export function formatUntil(target, current, options) {
45
+ return formatDuration(getDuration(target, current), options);
46
+ }
52
47
  /** Compact when a date will happen, e.g. `10d` or `2h` or `-1w` */
53
- export const formatAgo = (target, current) => formatDuration(getDuration(current, target));
48
+ export function formatAgo(target, current, options) {
49
+ return formatDuration(getDuration(current, target), options);
50
+ }
package/util/error.d.ts CHANGED
@@ -1,4 +1,17 @@
1
+ /**
2
+ * Valid error codes in gRPC.
3
+ * See also: https://firebase.google.com/docs/reference/node/firebase.firestore#firestoreerrorcode
4
+ */
5
+ export type ErrorCode = "cancelled" | "unknown" | "invalid-argument" | "deadline-exceeded" | "not-found" | "already-exists" | "permission-denied" | "resource-exhausted" | "failed-precondition" | "aborted" | "out-of-range" | "unimplemented" | "internal" | "unavailable" | "data-loss" | "unauthenticated";
1
6
  /** Callback function that reports an error. */
2
7
  export type Report = (reason: unknown) => void;
3
8
  /** Log an error to the console. */
4
9
  export declare const logError: Report;
10
+ /** Is an unknown value an `Error` instance? */
11
+ export declare function isError(v: unknown): v is Error & {
12
+ readonly code?: string | undefined;
13
+ };
14
+ /** Get the string `.code` property from an object or error, or `undefined` if it doesn't exist. */
15
+ export declare function getOptionalErrorCode(v: unknown): string | undefined;
16
+ /** Get the string `.code` property from an object or error, or throw `ValueError` if it doesn't exist. */
17
+ export declare function getErrorCode(v: unknown): string | undefined;
package/util/error.js CHANGED
@@ -1,3 +1,22 @@
1
+ import { ValueError } from "../error/ValueError.js";
2
+ import { isObject } from "./object.js";
3
+ import { isString } from "./string.js";
1
4
  /** Log an error to the console. */
2
5
  // eslint-disable-next-line no-console
3
6
  export const logError = reason => console.error(reason);
7
+ /** Is an unknown value an `Error` instance? */
8
+ export function isError(v) {
9
+ return v instanceof Error;
10
+ }
11
+ /** Get the string `.code` property from an object or error, or `undefined` if it doesn't exist. */
12
+ export function getOptionalErrorCode(v) {
13
+ if (isObject(v) && isString(v.code))
14
+ return v.code;
15
+ }
16
+ /** Get the string `.code` property from an object or error, or throw `ValueError` if it doesn't exist. */
17
+ export function getErrorCode(v) {
18
+ const code = getOptionalErrorCode(v);
19
+ if (typeof code !== "string")
20
+ throw new ValueError("Error code must be string", v);
21
+ return code;
22
+ }
package/util/function.js CHANGED
@@ -1,10 +1,10 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.js";
2
2
  /** Is a value a function? */
3
3
  export const isFunction = (value) => typeof value === "function";
4
4
  /** Assert that a value is a function. */
5
5
  export function assertFunction(value) {
6
6
  if (typeof value !== "function")
7
- throw new AssertionError("Must be function", value);
7
+ throw new ValueError("Must be function", value);
8
8
  }
9
9
  /** Function that just passes through the first argument. */
10
10
  export const PASSTHROUGH = (value) => value;
package/util/number.d.ts CHANGED
@@ -31,7 +31,7 @@ export declare function assertMin(value: unknown, min: number): asserts value is
31
31
  export declare function getOptionalNumber(value: unknown): number | undefined;
32
32
  /**
33
33
  * Assertively convert an unknown value to a finite number.
34
- * @throws `AssertionError` if the value cannot be converted.
34
+ * @throws `ValueError` if the value cannot be converted.
35
35
  */
36
36
  export declare function getNumber(value: unknown): number;
37
37
  /**
@@ -86,7 +86,7 @@ export declare function formatNumber(num: number, options?: NumberOptions): stri
86
86
  /** Format a number range (based on the user's browser language settings). */
87
87
  export declare function formatRange(min: number, max: number, options?: NumberOptions): string;
88
88
  /** Format a number with a short suffix, e.g. `1,000 kg` */
89
- export declare const formatQuantity: (num: number, abbr: string, options?: NumberOptions) => string;
89
+ export declare function formatQuantity(num: number, abbr: string, options?: NumberOptions): string;
90
90
  /** Format a number with a longer full-word suffix. */
91
91
  export declare function pluralizeQuantity(num: number, singular: string, plural: string, options?: NumberOptions): string;
92
92
  /**
package/util/number.js CHANGED
@@ -1,16 +1,16 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.js";
2
2
  import { NNBSP } from "./constants.js";
3
3
  /** Is a value a number? */
4
4
  export const isNumber = (value) => typeof value === "number";
5
5
  /** Assert that a value is a number. */
6
6
  export function assertNumber(value) {
7
7
  if (typeof value !== "number")
8
- throw new AssertionError(`Must be number`, value);
8
+ throw new ValueError(`Must be number`, value);
9
9
  }
10
10
  /** Assert that a value is a number greater than. */
11
11
  export function assertFinite(value) {
12
12
  if (typeof value !== "number" || !Number.isFinite(value))
13
- throw new AssertionError(`Must be finite number`, value);
13
+ throw new ValueError(`Must be finite number`, value);
14
14
  }
15
15
  /**
16
16
  * Is a finite number within a specified range?
@@ -23,17 +23,17 @@ export const isBetween = (num, min, max) => num >= min && num <= max;
23
23
  /** Assert that a value is a number greater than. */
24
24
  export function assertBetween(value, min, max) {
25
25
  if (typeof value !== "number" || isBetween(value, min, max))
26
- throw new AssertionError(`Must be number between ${min} and ${max}`, value);
26
+ throw new ValueError(`Must be number between ${min} and ${max}`, value);
27
27
  }
28
28
  /** Assert that a value is a number greater than. */
29
29
  export function assertMax(value, max) {
30
30
  if (typeof value !== "number" || value > max)
31
- throw new AssertionError(`Must be number with maximum ${max}`, value);
31
+ throw new ValueError(`Must be number with maximum ${max}`, value);
32
32
  }
33
33
  /** Assert that a value is a number less than. */
34
34
  export function assertMin(value, min) {
35
35
  if (typeof value !== "number" || value < min)
36
- throw new AssertionError(`Must be number with minimum ${min}`, value);
36
+ throw new ValueError(`Must be number with minimum ${min}`, value);
37
37
  }
38
38
  /**
39
39
  * Convert an unknown value to a finite number or `undefined`
@@ -56,7 +56,7 @@ export function getOptionalNumber(value) {
56
56
  const NOT_NUMERIC_REGEXP = /[^0-9-.]/g;
57
57
  /**
58
58
  * Assertively convert an unknown value to a finite number.
59
- * @throws `AssertionError` if the value cannot be converted.
59
+ * @throws `ValueError` if the value cannot be converted.
60
60
  */
61
61
  export function getNumber(value) {
62
62
  const num = getOptionalNumber(value);
@@ -128,7 +128,10 @@ export function formatRange(min, max, options) {
128
128
  return `${formatNumber(min, options)}–${formatNumber(max, options)}`;
129
129
  }
130
130
  /** Format a number with a short suffix, e.g. `1,000 kg` */
131
- export const formatQuantity = (num, abbr, options) => `${formatNumber(num, options)}${NNBSP}${abbr}`;
131
+ export function formatQuantity(num, abbr, options) {
132
+ const str = formatNumber(num, options);
133
+ return `${str}${str.length > 2 || abbr.length > 2 ? NNBSP : ""}${abbr}`;
134
+ }
132
135
  /** Format a number with a longer full-word suffix. */
133
136
  export function pluralizeQuantity(num, singular, plural, options) {
134
137
  const qty = formatNumber(num, options);
package/util/object.d.ts CHANGED
@@ -27,7 +27,7 @@ export declare function assertPlainObject(value: unknown): asserts value is Immu
27
27
  export declare const isProp: <T extends ImmutableObject<PropertyKey, unknown>>(obj: T, key: PropertyKey) => key is keyof T;
28
28
  /** Assert that an unknown value is the key for an own prop of an object. */
29
29
  export declare function assertProp<T extends ImmutableObject>(obj: T, key: PropertyKey): asserts key is keyof T;
30
- /** turn a possible object into an object. */
30
+ /** Turn a possible object into an object. */
31
31
  export declare function getObject<T extends ImmutableObject>(obj: PossibleObject<T>): T;
32
32
  /**
33
33
  * Mutable type is the opposite of `Readonly<T>` helper type.
package/util/object.js CHANGED
@@ -27,7 +27,7 @@ export function assertProp(obj, key) {
27
27
  if (!isProp(obj, key))
28
28
  throw new AssertionError("Must be object prop", key);
29
29
  }
30
- /** turn a possible object into an object. */
30
+ /** Turn a possible object into an object. */
31
31
  export function getObject(obj) {
32
32
  return isIterable(obj) ? Object.fromEntries(obj) : obj;
33
33
  }
package/util/optional.js CHANGED
@@ -2,7 +2,7 @@ import { RequiredError } from "../error/RequiredError.js";
2
2
  /** Get a required value. */
3
3
  export function getRequired(value) {
4
4
  if (value === null || value === undefined)
5
- throw new RequiredError("Value is required");
5
+ throw new RequiredError();
6
6
  return value;
7
7
  }
8
8
  /** Is a value not optional? */
package/util/regexp.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.js";
2
2
  import { getArray } from "./array.js";
3
3
  /** Regular expression that always matches everything. */
4
4
  export const ALWAYS_REGEXP = /^.*$/;
@@ -9,7 +9,7 @@ export const isRegExp = (value) => value instanceof RegExp;
9
9
  /** Assert that an unknown value is a `RegExp` instance. */
10
10
  export function assertRegExp(value) {
11
11
  if (!(value instanceof RegExp))
12
- throw new AssertionError("Must be regular expression", value);
12
+ throw new ValueError("Must be regular expression", value);
13
13
  }
14
14
  export function getRegExp(pattern, flags) {
15
15
  return typeof pattern === "string" ? new RegExp(pattern, flags) : pattern;
package/util/string.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable no-control-regex */
2
2
  import { AssertionError } from "../error/AssertionError.js";
3
+ import { ValueError } from "../error/ValueError.js";
3
4
  import { getArray, isArray } from "./array.js";
4
5
  import { formatDate, isDate } from "./date.js";
5
6
  import { formatNumber, formatRange, isBetween } from "./number.js";
@@ -9,7 +10,7 @@ export const isString = (value) => typeof value === "string";
9
10
  /** Assert that a value is a string. */
10
11
  export function assertString(value) {
11
12
  if (typeof value !== "string")
12
- throw new AssertionError(`Must be string`, value);
13
+ throw new ValueError(`Must be string`, value);
13
14
  }
14
15
  /**
15
16
  * Convert an unknown value into a title string for user-facing use.
package/util/time.d.ts CHANGED
@@ -40,7 +40,7 @@ export declare const isTime: (value: unknown) => value is Time;
40
40
  * - Works with time strings, e.g. `18:32` or `23:59:59.999`
41
41
  */
42
42
  export declare function getOptionalTime(possible: unknown): Time | undefined;
43
- /** Convert a possible time to a `Time` instance, or throw `AssertionError` if it couldn't be converted. */
43
+ /** Convert a possible time to a `Time` instance, or throw `ValueError` if it couldn't be converted. */
44
44
  export declare function getTime(possible?: PossibleTime): Time;
45
45
  /** Get the time as in `hh:mm` format (hours, minutes), e.g. `13.59` */
46
46
  export declare const getShortTime: (time?: PossibleTime) => string;
package/util/time.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.js";
2
2
  import { DAY, HOUR, MINUTE, SECOND } from "./constants.js";
3
3
  import { getOptionalDate } from "./date.js";
4
4
  import { wrapNumber } from "./number.js";
@@ -94,11 +94,11 @@ export const isTime = (value) => value instanceof Time;
94
94
  export function getOptionalTime(possible) {
95
95
  return Time.from(possible);
96
96
  }
97
- /** Convert a possible time to a `Time` instance, or throw `AssertionError` if it couldn't be converted. */
97
+ /** Convert a possible time to a `Time` instance, or throw `ValueError` if it couldn't be converted. */
98
98
  export function getTime(possible) {
99
99
  const time = getOptionalTime(possible);
100
100
  if (!time)
101
- throw new AssertionError(`Must be time`, possible);
101
+ throw new ValueError(`Must be 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/undefined.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.js";
2
2
  /** Function that always returns undefined. */
3
3
  export const getUndefined = () => undefined;
4
4
  /** Is a value undefined? */
@@ -10,7 +10,7 @@ export const notUndefined = isDefined;
10
10
  /** Assert that a value is not `undefined` */
11
11
  export function assertDefined(value) {
12
12
  if (value === undefined)
13
- throw new AssertionError("Must be defined", value);
13
+ throw new ValueError("Must be defined", value);
14
14
  }
15
15
  /** Get a defined value. */
16
16
  export function getDefined(value) {
package/util/units.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ConditionError } from "../error/ConditionError.js";
1
+ import { AssertionError } from "../error/AssertionError.js";
2
2
  import { RequiredError } from "../error/RequiredError.js";
3
3
  import { DAY, HOUR, MILLION, MINUTE, MONTH, NNBSP, SECOND, WEEK, YEAR } from "./constants.js";
4
4
  import { ImmutableMap } from "./map.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 ConditionError(`Cannot convert "${this.key}" to "${unit.key}"`);
66
+ throw new AssertionError(`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) {
@@ -102,7 +102,7 @@ export class UnitList extends ImmutableMap {
102
102
  getUnit(units) {
103
103
  if (this.has(units))
104
104
  return this.get(units);
105
- throw new RequiredError(`Unit "${units}" not found`);
105
+ throw new RequiredError(`Unknown unit`, units);
106
106
  }
107
107
  }
108
108
  // Distance constants.
package/util/url.d.ts CHANGED
@@ -7,7 +7,7 @@ export declare const isURL: (value: unknown) => value is URL;
7
7
  export declare function assertURL(value: unknown): asserts value is URL;
8
8
  /** Convert a possible URL to a URL or return `null` if conversion fails. */
9
9
  export declare function getOptionalURL(url: Optional<PossibleURL>, base?: PossibleURL | Location | undefined): URL | undefined;
10
- /** Convert a possible URL to a URL but throw `AssertionError` if conversion fails. */
10
+ /** Convert a possible URL to a URL but throw `ValueError` if conversion fails. */
11
11
  export declare function getURL(possibleURL: PossibleURL, base?: PossibleURL): URL;
12
12
  /** Just get important part of a URL, e.g. `http://shax.com/test?uid=129483` → `shax.com/test` */
13
13
  export declare function formatURL(possibleURL: PossibleURL, base?: PossibleURL): string;
package/util/url.js CHANGED
@@ -1,11 +1,11 @@
1
- import { AssertionError } from "../error/AssertionError.js";
1
+ import { ValueError } from "../error/ValueError.js";
2
2
  import { notOptional } from "./optional.js";
3
3
  /** Is an unknown value a URL? */
4
4
  export const isURL = (value) => value instanceof URL;
5
5
  /** Assert that an unknown value is a URL. */
6
6
  export function assertURL(value) {
7
7
  if (!isURL(value))
8
- throw new AssertionError("Invalid URL", value);
8
+ throw new ValueError("Invalid URL", value);
9
9
  }
10
10
  /** Convert a possible URL to a URL or return `null` if conversion fails. */
11
11
  export function getOptionalURL(url, base = _LOCATION) {
@@ -21,11 +21,11 @@ export function getOptionalURL(url, base = _LOCATION) {
21
21
  }
22
22
  }
23
23
  const _LOCATION = typeof window === "object" ? window.location : undefined;
24
- /** Convert a possible URL to a URL but throw `AssertionError` if conversion fails. */
24
+ /** Convert a possible URL to a URL but throw `ValueError` if conversion fails. */
25
25
  export function getURL(possibleURL, base) {
26
26
  const url = getOptionalURL(possibleURL, base);
27
27
  if (!url)
28
- throw new AssertionError("Invalid URL", possibleURL);
28
+ throw new ValueError("Invalid URL", possibleURL);
29
29
  return url;
30
30
  }
31
31
  /** Just get important part of a URL, e.g. `http://shax.com/test?uid=129483` → `shax.com/test` */
package/util/validate.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ValidationError } from "../error/ValidationError.js";
1
+ import { ValueError } from "../error/ValueError.js";
2
2
  import { Feedback } from "../feedback/Feedback.js";
3
3
  import { Feedbacks } from "../feedback/Feedbacks.js";
4
4
  import { getLastItem, isArray } from "./array.js";
@@ -13,7 +13,7 @@ export function getValid(unsafeValue, validator) {
13
13
  }
14
14
  catch (thrown) {
15
15
  if (thrown instanceof Feedback)
16
- throw new ValidationError("Must validate", thrown);
16
+ throw new ValueError("Must validate", thrown);
17
17
  throw thrown;
18
18
  }
19
19
  }
@@ -1,7 +0,0 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /**
3
- * Thrown if the program is in a condition it shouldn't have reached.
4
- * e.g. writing to a stream that's already closed
5
- */
6
- export declare class ConditionError extends AssertionError {
7
- }
@@ -1,8 +0,0 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /**
3
- * Thrown if the program is in a condition it shouldn't have reached.
4
- * e.g. writing to a stream that's already closed
5
- */
6
- export class ConditionError extends AssertionError {
7
- }
8
- ConditionError.prototype.name = "ConditionError";
@@ -1,4 +0,0 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /** Thrown if a method isn't supported. */
3
- export declare class UnsupportedError extends AssertionError {
4
- }
@@ -1,5 +0,0 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /** Thrown if a method isn't supported. */
3
- export class UnsupportedError extends AssertionError {
4
- }
5
- UnsupportedError.prototype.name = "UnsupportedError";
@@ -1,4 +0,0 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /** Thrown if a value isn't valid. */
3
- export declare class ValidationError extends AssertionError {
4
- }
@@ -1,5 +0,0 @@
1
- import { AssertionError } from "./AssertionError.js";
2
- /** Thrown if a value isn't valid. */
3
- export class ValidationError extends AssertionError {
4
- }
5
- ValidationError.prototype.name = "ValidationError";
@@ -1,2 +0,0 @@
1
- /** Convert a Firestore error (which use gRPC error codes) into a corresponding Shelving error. */
2
- export declare function convertFirestoreError(thrown: unknown): never;
@@ -1,19 +0,0 @@
1
- import { ConnectionError } from "../../error/ConnectionError.js";
2
- import { PermissionError } from "../../error/PermissionError.js";
3
- import { RequiredError } from "../../error/RequiredError.js";
4
- import { isObject } from "../../util/object.js";
5
- /** Convert a Firestore error (which use gRPC error codes) into a corresponding Shelving error. */
6
- export function convertFirestoreError(thrown) {
7
- if (isObject(thrown)) {
8
- const code = thrown.code;
9
- if (typeof code === "string") {
10
- if (code === "unavailable")
11
- throw new ConnectionError();
12
- if (code === "not-found")
13
- throw new RequiredError();
14
- if (code === "permission-denied")
15
- throw new PermissionError();
16
- }
17
- }
18
- throw thrown;
19
- }