shelving 1.82.1 → 1.83.1
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/constraint/Constraints.d.ts +1 -1
- package/constraint/Constraints.js +3 -3
- package/constraint/QueryConstraints.js +5 -5
- package/db/Query.js +4 -5
- package/feedback/Feedback.d.ts +2 -2
- package/feedback/Feedback.js +3 -2
- package/firestore/client/FirestoreClientProvider.js +2 -2
- package/firestore/lite/FirestoreLiteProvider.js +2 -2
- package/firestore/server/FirestoreServerProvider.js +2 -2
- package/package.json +1 -1
- package/provider/MemoryProvider.d.ts +1 -1
- package/provider/MemoryProvider.js +3 -3
- package/provider/ValidationProvider.js +2 -2
- package/schema/AllowSchema.d.ts +25 -24
- package/schema/AllowSchema.js +25 -29
- package/schema/ArraySchema.d.ts +2 -2
- package/schema/BooleanSchema.d.ts +2 -2
- package/schema/DataSchema.d.ts +2 -2
- package/schema/DataSchema.js +2 -2
- package/schema/DateSchema.d.ts +2 -2
- package/schema/DictionarySchema.d.ts +19 -0
- package/schema/{ObjectSchema.js → DictionarySchema.js} +6 -6
- package/schema/LinkSchema.d.ts +2 -2
- package/schema/NumberSchema.d.ts +2 -2
- package/schema/Schema.d.ts +10 -8
- package/schema/Schema.js +1 -1
- package/schema/StringSchema.d.ts +12 -10
- package/schema/index.d.ts +1 -1
- package/schema/index.js +1 -1
- package/state/ArrayState.js +2 -2
- package/state/DataState.js +3 -3
- package/state/DictionaryState.d.ts +15 -0
- package/state/{ObjectState.js → DictionaryState.js} +6 -6
- package/state/index.d.ts +2 -2
- package/state/index.js +2 -2
- package/test/basics.js +1 -1
- package/update/ArrayUpdate.d.ts +6 -6
- package/update/ArrayUpdate.js +19 -17
- package/update/DataUpdate.d.ts +5 -4
- package/update/DataUpdate.js +18 -14
- package/update/DictionaryUpdate.d.ts +24 -0
- package/update/{ObjectUpdate.js → DictionaryUpdate.js} +29 -31
- package/update/Increment.js +1 -0
- package/update/Update.d.ts +0 -2
- package/update/Update.js +1 -1
- package/update/hydrations.js +2 -2
- package/update/index.d.ts +1 -1
- package/update/index.js +1 -1
- package/util/array.d.ts +9 -5
- package/util/array.js +18 -7
- package/util/clone.d.ts +2 -2
- package/util/clone.js +5 -5
- package/util/data.d.ts +13 -52
- package/util/data.js +6 -1
- package/util/dictionary.d.ts +39 -0
- package/util/dictionary.js +33 -0
- package/util/diff.d.ts +3 -3
- package/util/entry.d.ts +7 -5
- package/util/entry.js +8 -6
- package/util/filter.d.ts +0 -5
- package/util/filter.js +0 -3
- package/util/hydrate.d.ts +2 -2
- package/util/hydrate.js +7 -8
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/util/iterate.d.ts +7 -7
- package/util/iterate.js +22 -33
- package/util/map.d.ts +18 -4
- package/util/map.js +10 -6
- package/util/merge.d.ts +3 -6
- package/util/merge.js +4 -6
- package/util/object.d.ts +77 -49
- package/util/object.js +22 -31
- package/util/set.d.ts +1 -1
- package/util/set.js +1 -1
- package/util/template.d.ts +3 -3
- package/util/template.js +3 -3
- package/util/transform.d.ts +21 -44
- package/util/transform.js +21 -39
- package/util/units.d.ts +6 -12
- package/util/units.js +9 -5
- package/util/validate.d.ts +4 -3
- package/util/validate.js +3 -2
- package/schema/ObjectSchema.d.ts +0 -19
- package/state/ObjectState.d.ts +0 -16
- package/update/ObjectUpdate.d.ts +0 -29
|
@@ -14,7 +14,7 @@ export declare abstract class Constraints<T extends Data, C extends Constraint<P
|
|
|
14
14
|
/** Clone this set of constraints but add additional constraints. */
|
|
15
15
|
with(...constraints: C[]): this;
|
|
16
16
|
/** Clone this set of constraints but remove specific constraints. */
|
|
17
|
-
|
|
17
|
+
omit(...constraints: C[]): this;
|
|
18
18
|
/** Iterate over the constraints. */
|
|
19
19
|
[Symbol.iterator](): Iterator<C, void>;
|
|
20
20
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { withArrayItems,
|
|
1
|
+
import { withArrayItems, omitArrayItems } from "../util/array.js";
|
|
2
2
|
import { Constraint } from "./Constraint.js";
|
|
3
3
|
/** Type of Rule that is powered by several sub-constraints (e.g. `Filters` and `Sorts` and `Query` itself extend this). */
|
|
4
4
|
export class Constraints extends Constraint {
|
|
@@ -24,8 +24,8 @@ export class Constraints extends Constraint {
|
|
|
24
24
|
return _constraints !== this._constraints ? { __proto__: Object.getPrototypeOf(this), ...this, _constraints: _constraints } : this;
|
|
25
25
|
}
|
|
26
26
|
/** Clone this set of constraints but remove specific constraints. */
|
|
27
|
-
|
|
28
|
-
const _constraints =
|
|
27
|
+
omit(...constraints) {
|
|
28
|
+
const _constraints = omitArrayItems(this._constraints, ...constraints);
|
|
29
29
|
return _constraints !== this._constraints ? { __proto__: Object.getPrototypeOf(this), ...this, _constraints: _constraints } : this;
|
|
30
30
|
}
|
|
31
31
|
/** Iterate over the constraints. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getProp } from "../util/object.js";
|
|
2
2
|
import { assert } from "../util/assert.js";
|
|
3
|
-
import {
|
|
3
|
+
import { limitArray } from "../util/array.js";
|
|
4
4
|
import { FilterConstraints } from "./FilterConstraints.js";
|
|
5
5
|
import { SortConstraints } from "./SortConstraints.js";
|
|
6
6
|
import { Constraint } from "./Constraint.js";
|
|
@@ -83,7 +83,7 @@ export class QueryConstraints extends Constraint {
|
|
|
83
83
|
// Implement `Rule`
|
|
84
84
|
transform(items) {
|
|
85
85
|
const sorted = this.sorts.transform(this.filters.transform(items));
|
|
86
|
-
return typeof this.limit === "number" ?
|
|
86
|
+
return typeof this.limit === "number" ? limitArray(sorted, this.limit) : sorted;
|
|
87
87
|
}
|
|
88
88
|
// Implement toString()
|
|
89
89
|
toString() {
|
|
@@ -96,7 +96,7 @@ function* _getAfterFilters(sorts, item) {
|
|
|
96
96
|
for (const sort of sorts) {
|
|
97
97
|
const { key, direction } = sort;
|
|
98
98
|
const filterKey = direction === "ASC" ? (sort === lastSort ? `${key}>` : `${key}>=`) : sort === lastSort ? `${key}<` : `${key}<=`;
|
|
99
|
-
yield new FilterConstraint(filterKey,
|
|
99
|
+
yield new FilterConstraint(filterKey, getProp(item, key));
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
function* _getBeforeFilters(sorts, item) {
|
|
@@ -105,6 +105,6 @@ function* _getBeforeFilters(sorts, item) {
|
|
|
105
105
|
for (const sort of sorts) {
|
|
106
106
|
const { key, direction } = sort;
|
|
107
107
|
const filterKey = direction === "ASC" ? (sort === lastSort ? `${key}<` : `${key}<=`) : sort === lastSort ? `${key}>` : `${key}>=`;
|
|
108
|
-
yield new FilterConstraint(filterKey,
|
|
108
|
+
yield new FilterConstraint(filterKey, getProp(item, key));
|
|
109
109
|
}
|
|
110
110
|
}
|
package/db/Query.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { getFirstItem, getLastItem, getOptionalFirstItem, getOptionalLastItem } from "../util/array.js";
|
|
2
|
-
import { countItems, hasItems } from "../util/iterate.js";
|
|
1
|
+
import { getFirstItem, getLastItem, getOptionalFirstItem, getOptionalLastItem, isArrayMin, countArray } from "../util/array.js";
|
|
3
2
|
import { runSequence } from "../util/sequence.js";
|
|
4
3
|
import { QueryConstraints } from "../constraint/QueryConstraints.js";
|
|
5
4
|
/** Reference to a set of items in a sync or async provider. */
|
|
@@ -31,7 +30,7 @@ export class Query extends BaseQuery {
|
|
|
31
30
|
return this.value.length;
|
|
32
31
|
}
|
|
33
32
|
get exists() {
|
|
34
|
-
return
|
|
33
|
+
return !!this.max(1).value.length;
|
|
35
34
|
}
|
|
36
35
|
get firstValue() {
|
|
37
36
|
return getOptionalFirstItem(this.max(1).value);
|
|
@@ -66,10 +65,10 @@ export class AsyncQuery extends BaseQuery {
|
|
|
66
65
|
return this.db.provider.getQuery(this.collection, this);
|
|
67
66
|
}
|
|
68
67
|
get count() {
|
|
69
|
-
return this.value.then(
|
|
68
|
+
return this.value.then(countArray);
|
|
70
69
|
}
|
|
71
70
|
get exists() {
|
|
72
|
-
return this.max(1).value.then(
|
|
71
|
+
return this.max(1).value.then(isArrayMin);
|
|
73
72
|
}
|
|
74
73
|
get firstValue() {
|
|
75
74
|
return this.max(1).value.then(getOptionalFirstItem);
|
package/feedback/Feedback.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ImmutableDictionary } from "../util/dictionary.js";
|
|
2
2
|
/**
|
|
3
3
|
* The `Feedback` class represents a feedback message that should be shown to the user.
|
|
4
4
|
* - Basic `Feedback` is neither good nor bad, `SuccessFeedback` indicates good news, and `ErrorFeedback` indicates bad news.
|
|
@@ -24,4 +24,4 @@ export declare const isFeedback: <T extends Feedback<unknown>>(v: unknown) => v
|
|
|
24
24
|
* Get an object of sub-messages in `{ key: message }` format from a feedback's value.
|
|
25
25
|
* - Takes the `.value` property from a `Feedback` instance and looks for keyed `Feedback` instances in either `{ key: Feedback }`. `Feedback[]`, or `Map<key, Feedback>` formats.
|
|
26
26
|
*/
|
|
27
|
-
export declare const getFeedbackMessages: ({ value }: Feedback) =>
|
|
27
|
+
export declare const getFeedbackMessages: ({ value }: Feedback) => ImmutableDictionary<string>;
|
package/feedback/Feedback.js
CHANGED
|
@@ -4,9 +4,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { isObject } from "../util/object.js";
|
|
8
7
|
import { getEntries } from "../util/entry.js";
|
|
9
8
|
import { setPrototype } from "../util/class.js";
|
|
9
|
+
import { isObject } from "../util/object.js";
|
|
10
|
+
import { getString } from "../util/string.js";
|
|
10
11
|
/**
|
|
11
12
|
* The `Feedback` class represents a feedback message that should be shown to the user.
|
|
12
13
|
* - Basic `Feedback` is neither good nor bad, `SuccessFeedback` indicates good news, and `ErrorFeedback` indicates bad news.
|
|
@@ -38,5 +39,5 @@ function* _yieldFeedbackMessages(value) {
|
|
|
38
39
|
if (isObject(value))
|
|
39
40
|
for (const [k, v] of getEntries(value))
|
|
40
41
|
if (isFeedback(v))
|
|
41
|
-
yield [k, v.message];
|
|
42
|
+
yield [getString(k), v.message];
|
|
42
43
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { orderBy as firestoreOrderBy, where as firestoreWhere, limit as firestoreLimit, increment as firestoreIncrement, arrayUnion as firestoreArrayUnion, arrayRemove as firestoreArrayRemove, deleteField as firestoreDeleteField, collection as firestoreCollection, doc as firestoreDocument, query as firestoreQuery, onSnapshot, addDoc, setDoc, updateDoc, deleteDoc, getDoc, getDocs, } from "firebase/firestore";
|
|
2
2
|
import { LazyDeferredSequence } from "../../sequence/LazyDeferredSequence.js";
|
|
3
|
-
import { ArrayUpdate, DataUpdate, Increment,
|
|
3
|
+
import { ArrayUpdate, DataUpdate, Increment, DictionaryUpdate, Delete, Update } from "../../update/index.js";
|
|
4
4
|
// Constants.
|
|
5
5
|
// const ID = "__name__"; // DH: `__name__` is the entire path of the document. `__id__` is just ID.
|
|
6
6
|
const ID = "__id__"; // Internal way Firestore Queries can reference the ID of the current document.
|
|
@@ -47,7 +47,7 @@ function _getItemValue(snapshot) {
|
|
|
47
47
|
/** Convert `Update` instances into corresponding Firestore `FieldValue` instances. */
|
|
48
48
|
function* _getFieldValues(updates, prefix = "") {
|
|
49
49
|
for (const [key, update] of updates) {
|
|
50
|
-
if (update instanceof DataUpdate || update instanceof
|
|
50
|
+
if (update instanceof DataUpdate || update instanceof DictionaryUpdate) {
|
|
51
51
|
yield* _getFieldValues(update, `${prefix}${key}.`);
|
|
52
52
|
}
|
|
53
53
|
else if (update instanceof ArrayUpdate) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { orderBy as firestoreOrderBy, where as firestoreWhere, limit as firestoreLimit, increment as firestoreIncrement, arrayUnion as firestoreArrayUnion, arrayRemove as firestoreArrayRemove, deleteField as firestoreDeleteField, collection as firestoreCollection, doc as firestoreDocument, query as firestoreQuery, setDoc, addDoc, updateDoc, deleteDoc, getDoc, getDocs, } from "firebase/firestore/lite";
|
|
2
2
|
import { UnsupportedError } from "../../error/UnsupportedError.js";
|
|
3
|
-
import { ArrayUpdate, DataUpdate, Increment,
|
|
3
|
+
import { ArrayUpdate, DataUpdate, Increment, DictionaryUpdate, Delete, Update } from "../../update/index.js";
|
|
4
4
|
// Constants.
|
|
5
5
|
// const ID = "__name__"; // DH: `__name__` is the entire path of the document. `__id__` is just ID.
|
|
6
6
|
const ID = "__id__"; // Internal way Firestore Queries can reference the ID of the current document.
|
|
@@ -47,7 +47,7 @@ function _getItemValue(snapshot) {
|
|
|
47
47
|
/** Convert `Update` instances into corresponding Firestore `FieldValue` instances. */
|
|
48
48
|
function* _getFieldValues(updates, prefix = "") {
|
|
49
49
|
for (const [key, update] of updates) {
|
|
50
|
-
if (update instanceof DataUpdate || update instanceof
|
|
50
|
+
if (update instanceof DataUpdate || update instanceof DictionaryUpdate) {
|
|
51
51
|
yield* _getFieldValues(update, `${prefix}${key}.`);
|
|
52
52
|
}
|
|
53
53
|
else if (update instanceof ArrayUpdate) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Firestore, FieldValue as FirestoreFieldValue } from "@google-cloud/firestore";
|
|
2
2
|
import { LazyDeferredSequence } from "../../sequence/LazyDeferredSequence.js";
|
|
3
|
-
import { ArrayUpdate, DataUpdate, Increment,
|
|
3
|
+
import { ArrayUpdate, DataUpdate, Increment, DictionaryUpdate, Delete, Update } from "../../update/index.js";
|
|
4
4
|
// Constants.
|
|
5
5
|
// const ID = "__name__"; // DH: `__name__` is the entire path of the document. `__id__` is just ID.
|
|
6
6
|
const ID = "__id__"; // Internal way Firestore Queries can reference the ID of the current document.
|
|
@@ -47,7 +47,7 @@ function _getItemValue(snapshot) {
|
|
|
47
47
|
/** Convert `Update` instances into corresponding Firestore `FieldValue` instances. */
|
|
48
48
|
function* _getFieldValues(updates, prefix = "") {
|
|
49
49
|
for (const [key, update] of updates) {
|
|
50
|
-
if (update instanceof DataUpdate || update instanceof
|
|
50
|
+
if (update instanceof DataUpdate || update instanceof DictionaryUpdate) {
|
|
51
51
|
yield* _getFieldValues(update, `${prefix}${key}.`);
|
|
52
52
|
}
|
|
53
53
|
else if (update instanceof ArrayUpdate) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Data, Datas, DataKey } from "../util/data.js";
|
|
2
2
|
import type { ItemArray, ItemValue, ItemData, ItemConstraints } from "../db/Item.js";
|
|
3
|
-
import
|
|
3
|
+
import { Updates } from "../update/DataUpdate.js";
|
|
4
4
|
import { DeferredSequence } from "../sequence/DeferredSequence.js";
|
|
5
5
|
import type { Provider } from "./Provider.js";
|
|
6
6
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { updateData } from "../update/DataUpdate.js";
|
|
1
2
|
import { QueryConstraints } from "../constraint/QueryConstraints.js";
|
|
2
3
|
import { getRandomKey } from "../util/random.js";
|
|
3
4
|
import { isArrayEqual } from "../util/equal.js";
|
|
4
5
|
import { RequiredError } from "../error/RequiredError.js";
|
|
5
6
|
import { getArray } from "../util/array.js";
|
|
6
|
-
import { transformData } from "../util/transform.js";
|
|
7
7
|
import { DeferredSequence } from "../sequence/DeferredSequence.js";
|
|
8
8
|
/**
|
|
9
9
|
* Fast in-memory store for data.
|
|
@@ -135,7 +135,7 @@ export class MemoryTable {
|
|
|
135
135
|
const item = this._data.get(id);
|
|
136
136
|
if (!item)
|
|
137
137
|
throw new RequiredError(`Document "${id}" does not exist`);
|
|
138
|
-
this._data.set(id, { ...
|
|
138
|
+
this._data.set(id, { ...updateData(item, updates), id });
|
|
139
139
|
this._times.set(id, Date.now());
|
|
140
140
|
this._changed.resolve();
|
|
141
141
|
}
|
|
@@ -231,7 +231,7 @@ export class MemoryTable {
|
|
|
231
231
|
let count = 0;
|
|
232
232
|
for (const item of _getWriteConstraints(constraints).transform(this._data.values())) {
|
|
233
233
|
const id = item.id;
|
|
234
|
-
this._data.set(id, { ...
|
|
234
|
+
this._data.set(id, { ...updateData(item, updates), id });
|
|
235
235
|
this._times.set(id, now);
|
|
236
236
|
count++;
|
|
237
237
|
}
|
|
@@ -103,9 +103,9 @@ function _validateItem(collection, unsafeEntity, schema) {
|
|
|
103
103
|
}
|
|
104
104
|
/** Validate a set of entities for this query reference. */
|
|
105
105
|
function _validateItems(collection, unsafeEntities, schema) {
|
|
106
|
-
return Array.from(
|
|
106
|
+
return Array.from(_yieldValidItems(collection, unsafeEntities, schema));
|
|
107
107
|
}
|
|
108
|
-
function*
|
|
108
|
+
function* _yieldValidItems(collection, unsafeEntities, schema) {
|
|
109
109
|
let invalid = false;
|
|
110
110
|
const details = {};
|
|
111
111
|
for (const unsafeEntity of unsafeEntities) {
|
package/schema/AllowSchema.d.ts
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { Entry } from "../util/entry.js";
|
|
2
|
+
import { ImmutableRequiredMap, PossibleMap, PossibleStringMap } from "../util/map.js";
|
|
3
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
4
|
+
/** Options for an `AllowSchema` instance. */
|
|
5
|
+
declare type AllowSchemaOptions<K, T> = SchemaOptions & {
|
|
6
|
+
allow: PossibleMap<K, T>;
|
|
7
|
+
value?: K | null;
|
|
5
8
|
};
|
|
6
|
-
/** Validate a value against a specific set of allowed values. */
|
|
7
|
-
export declare function validateAllowed<T extends string | number>(value: unknown, allowed: Allowed<T>): T;
|
|
8
9
|
/** Define a valid value from an allowed set of values. */
|
|
9
|
-
export declare
|
|
10
|
-
readonly value:
|
|
11
|
-
readonly allow:
|
|
12
|
-
constructor({ allow, value, ...options }:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
/** Define a valid string from an allowed set of strings. */
|
|
18
|
-
export declare class AllowStringSchema<T extends string> extends AllowSchema<T> {
|
|
19
|
-
validate(unsafeValue?: unknown): T;
|
|
10
|
+
export declare class AllowSchema<K, T> extends Schema<K> implements Iterable<Entry<K, T>> {
|
|
11
|
+
readonly value: K | null;
|
|
12
|
+
readonly allow: ImmutableRequiredMap<K, T>;
|
|
13
|
+
constructor({ allow, value, ...options }: AllowSchemaOptions<K, T>);
|
|
14
|
+
validate(value?: unknown): K;
|
|
15
|
+
/** Iterate over the the allowed options in `[key, value]` format. */
|
|
16
|
+
[Symbol.iterator](): Iterator<Entry<K, T>>;
|
|
20
17
|
}
|
|
21
|
-
/** Define a valid
|
|
22
|
-
export declare class
|
|
23
|
-
|
|
18
|
+
/** Define a valid string value from an allowed set of values. */
|
|
19
|
+
export declare class AllowStringSchema<K extends string, T> extends AllowSchema<K, T> {
|
|
20
|
+
constructor({ allow, ...options }: SchemaOptions & {
|
|
21
|
+
allow: PossibleStringMap<K, T>;
|
|
22
|
+
});
|
|
23
|
+
validator(value?: unknown): K;
|
|
24
24
|
}
|
|
25
|
-
/** Valid
|
|
26
|
-
export declare
|
|
27
|
-
/** Valid string from an allowed set of
|
|
28
|
-
export declare
|
|
25
|
+
/** Valid value from an allowed set of values. */
|
|
26
|
+
export declare function ALLOW<K, T>(allow: PossibleMap<K, T>): AllowSchema<K, T>;
|
|
27
|
+
/** Valid string from an allowed set of values. */
|
|
28
|
+
export declare function ALLOW_STRING<K extends string, T>(allow: PossibleStringMap<K, T>): AllowSchema<K, T>;
|
|
29
|
+
export {};
|
package/schema/AllowSchema.js
CHANGED
|
@@ -1,42 +1,38 @@
|
|
|
1
|
-
import { InvalidFeedback } from "../feedback/InvalidFeedback.js";
|
|
2
1
|
import { getString } from "../util/string.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { isObjectKey } from "../util/object.js";
|
|
2
|
+
import { getRequiredMap, isMapKey } from "../util/map.js";
|
|
3
|
+
import { InvalidFeedback } from "../feedback/InvalidFeedback.js";
|
|
6
4
|
import { Schema } from "./Schema.js";
|
|
7
|
-
/** Validate a value against a specific set of allowed values. */
|
|
8
|
-
export function validateAllowed(value, allowed) {
|
|
9
|
-
if (isArray(allowed)) {
|
|
10
|
-
if (isArrayItem(allowed, value))
|
|
11
|
-
return value;
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
if (isObjectKey(allowed, value))
|
|
15
|
-
return value;
|
|
16
|
-
}
|
|
17
|
-
throw new InvalidFeedback("Unknown value", { value });
|
|
18
|
-
}
|
|
19
5
|
/** Define a valid value from an allowed set of values. */
|
|
20
6
|
export class AllowSchema extends Schema {
|
|
21
7
|
constructor({ allow, value = null, ...options }) {
|
|
22
8
|
super(options);
|
|
23
|
-
this.allow = allow;
|
|
9
|
+
this.allow = getRequiredMap(allow);
|
|
24
10
|
this.value = value;
|
|
25
11
|
}
|
|
12
|
+
validate(value = this.value) {
|
|
13
|
+
if (isMapKey(this.allow, value))
|
|
14
|
+
return value;
|
|
15
|
+
throw new InvalidFeedback("Unknown value", { value });
|
|
16
|
+
}
|
|
17
|
+
/** Iterate over the the allowed options in `[key, value]` format. */
|
|
18
|
+
[Symbol.iterator]() {
|
|
19
|
+
return this.allow[Symbol.iterator]();
|
|
20
|
+
}
|
|
26
21
|
}
|
|
27
|
-
/** Define a valid string from an allowed set of
|
|
22
|
+
/** Define a valid string value from an allowed set of values. */
|
|
28
23
|
export class AllowStringSchema extends AllowSchema {
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
constructor({ allow, ...options }) {
|
|
25
|
+
super({ allow: getRequiredMap(allow), ...options });
|
|
31
26
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export class AllowNumberSchema extends AllowSchema {
|
|
35
|
-
validate(unsafeValue = this.value) {
|
|
36
|
-
return validateAllowed(getOptionalNumber(unsafeValue), this.allow);
|
|
27
|
+
validator(value = this.value) {
|
|
28
|
+
return super.validate(getString(value));
|
|
37
29
|
}
|
|
38
30
|
}
|
|
39
|
-
/** Valid
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
/** Valid value from an allowed set of values. */
|
|
32
|
+
export function ALLOW(allow) {
|
|
33
|
+
return new AllowSchema({ allow });
|
|
34
|
+
}
|
|
35
|
+
/** Valid string from an allowed set of values. */
|
|
36
|
+
export function ALLOW_STRING(allow) {
|
|
37
|
+
return new AllowStringSchema({ allow });
|
|
38
|
+
}
|
package/schema/ArraySchema.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ImmutableArray } from "../util/array.js";
|
|
2
2
|
import { Validator } from "../util/validate.js";
|
|
3
|
-
import { Schema } from "./Schema.js";
|
|
3
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
4
4
|
/**
|
|
5
5
|
* Define a valid array.
|
|
6
6
|
*
|
|
@@ -34,7 +34,7 @@ export declare class ArraySchema<T> extends Schema<ImmutableArray<T>> {
|
|
|
34
34
|
readonly unique: boolean;
|
|
35
35
|
readonly min: number;
|
|
36
36
|
readonly max: number | null;
|
|
37
|
-
constructor({ value, items, unique, min, max, ...options }:
|
|
37
|
+
constructor({ value, items, unique, min, max, ...options }: SchemaOptions & {
|
|
38
38
|
readonly value?: ImmutableArray;
|
|
39
39
|
readonly items: Validator<T>;
|
|
40
40
|
readonly min?: number;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Schema } from "./Schema.js";
|
|
1
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
2
2
|
/** Define a valid boolean. */
|
|
3
3
|
export declare class BooleanSchema extends Schema<boolean> {
|
|
4
4
|
readonly value: boolean;
|
|
5
|
-
constructor({ value, ...options }:
|
|
5
|
+
constructor({ value, ...options }: SchemaOptions & {
|
|
6
6
|
readonly value?: boolean;
|
|
7
7
|
});
|
|
8
8
|
validate(unsafeValue?: unknown): boolean;
|
package/schema/DataSchema.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Data, Datas } from "../util/data.js";
|
|
2
2
|
import { Validators } from "../util/validate.js";
|
|
3
3
|
import { OptionalSchema } from "./OptionalSchema.js";
|
|
4
|
-
import { Schema } from "./Schema.js";
|
|
4
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
5
5
|
/** Validate a data object. */
|
|
6
6
|
export declare class DataSchema<T extends Data> extends Schema<T> {
|
|
7
7
|
readonly value: Partial<T>;
|
|
8
8
|
readonly props: Validators<T>;
|
|
9
|
-
constructor({ value, props, ...options }:
|
|
9
|
+
constructor({ value, props, ...options }: SchemaOptions & {
|
|
10
10
|
readonly props: Validators<T>;
|
|
11
11
|
readonly value?: Partial<T>;
|
|
12
12
|
});
|
package/schema/DataSchema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { InvalidFeedback } from "../feedback/InvalidFeedback.js";
|
|
2
2
|
import { validateData } from "../util/validate.js";
|
|
3
|
-
import {
|
|
3
|
+
import { isData } from "../util/data.js";
|
|
4
4
|
import { OPTIONAL } from "./OptionalSchema.js";
|
|
5
5
|
import { Schema } from "./Schema.js";
|
|
6
6
|
/** Validate a data object. */
|
|
@@ -11,7 +11,7 @@ export class DataSchema extends Schema {
|
|
|
11
11
|
this.value = value;
|
|
12
12
|
}
|
|
13
13
|
validate(unsafeValue = this.value) {
|
|
14
|
-
if (!
|
|
14
|
+
if (!isData(unsafeValue))
|
|
15
15
|
throw new InvalidFeedback("Must be object", { value: unsafeValue });
|
|
16
16
|
return validateData(unsafeValue, this.props);
|
|
17
17
|
}
|
package/schema/DateSchema.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { PossibleDate } from "../util/date.js";
|
|
2
|
-
import { Schema } from "./Schema.js";
|
|
2
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
3
3
|
/** Define a valid date, e.g. `2005-09-12` */
|
|
4
4
|
export declare class DateSchema extends Schema<string> {
|
|
5
5
|
readonly value: PossibleDate;
|
|
6
6
|
readonly min: PossibleDate | null;
|
|
7
7
|
readonly max: PossibleDate | null;
|
|
8
|
-
constructor({ value, min, max, ...options }:
|
|
8
|
+
constructor({ value, min, max, ...options }: SchemaOptions & {
|
|
9
9
|
readonly value?: PossibleDate;
|
|
10
10
|
readonly min?: PossibleDate | null;
|
|
11
11
|
readonly max?: PossibleDate | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ImmutableDictionary } from "../util/dictionary.js";
|
|
2
|
+
import { Validator } from "../util/validate.js";
|
|
3
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
4
|
+
/** Validate a dictionary object (whose props are all the same with string keys). */
|
|
5
|
+
export declare class DictionarySchema<T> extends Schema<ImmutableDictionary<T>> {
|
|
6
|
+
readonly value: ImmutableDictionary;
|
|
7
|
+
readonly items: Validator<T>;
|
|
8
|
+
readonly min: number | null;
|
|
9
|
+
readonly max: number | null;
|
|
10
|
+
constructor({ value, items, min, max, ...rest }: SchemaOptions & {
|
|
11
|
+
readonly items: Validator<T>;
|
|
12
|
+
readonly value?: ImmutableDictionary;
|
|
13
|
+
readonly min?: number | null;
|
|
14
|
+
readonly max?: number | null;
|
|
15
|
+
});
|
|
16
|
+
validate(unsafeValue?: unknown): ImmutableDictionary<T>;
|
|
17
|
+
}
|
|
18
|
+
/** Valid dictionary object with specifed items. */
|
|
19
|
+
export declare const DICTIONARY: <T>(items: Validator<T>) => DictionarySchema<T>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isDictionary } from "../util/dictionary.js";
|
|
2
2
|
import { validateEntries } from "../util/validate.js";
|
|
3
3
|
import { InvalidFeedback } from "../feedback/InvalidFeedback.js";
|
|
4
4
|
import { Schema } from "./Schema.js";
|
|
5
|
-
/** Validate a
|
|
6
|
-
export class
|
|
5
|
+
/** Validate a dictionary object (whose props are all the same with string keys). */
|
|
6
|
+
export class DictionarySchema extends Schema {
|
|
7
7
|
constructor({ value = {}, items, min = null, max = null, ...rest }) {
|
|
8
8
|
super(rest);
|
|
9
9
|
this.min = null;
|
|
@@ -14,7 +14,7 @@ export class ObjectSchema extends Schema {
|
|
|
14
14
|
this.max = max;
|
|
15
15
|
}
|
|
16
16
|
validate(unsafeValue = this.value) {
|
|
17
|
-
if (!
|
|
17
|
+
if (!isDictionary(unsafeValue))
|
|
18
18
|
throw new InvalidFeedback("Must be object", { value: unsafeValue });
|
|
19
19
|
const unsafeEntries = Object.entries(unsafeValue);
|
|
20
20
|
const safeObject = Object.fromEntries(validateEntries(unsafeEntries, this.items));
|
|
@@ -25,5 +25,5 @@ export class ObjectSchema extends Schema {
|
|
|
25
25
|
return safeObject;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
/** Valid
|
|
29
|
-
export const
|
|
28
|
+
/** Valid dictionary object with specifed items. */
|
|
29
|
+
export const DICTIONARY = (items) => new DictionarySchema({ items });
|
package/schema/LinkSchema.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StringSchema } from "./StringSchema.js";
|
|
1
|
+
import { StringSchema, StringSchemaOptions } from "./StringSchema.js";
|
|
2
2
|
/**
|
|
3
3
|
* Type of `StringSchema` that defines a valid URL.
|
|
4
4
|
* - Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional).
|
|
@@ -11,7 +11,7 @@ export declare class LinkSchema extends StringSchema {
|
|
|
11
11
|
readonly max = 512;
|
|
12
12
|
readonly schemes: string[];
|
|
13
13
|
readonly hosts: string[] | null;
|
|
14
|
-
constructor({ schemes, hosts, ...rest }:
|
|
14
|
+
constructor({ schemes, hosts, ...rest }: StringSchemaOptions & {
|
|
15
15
|
readonly schemes?: string[];
|
|
16
16
|
readonly hosts?: string[] | null;
|
|
17
17
|
});
|
package/schema/NumberSchema.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Schema } from "./Schema.js";
|
|
1
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
2
2
|
/** Schema that defines a valid number. */
|
|
3
3
|
export declare class NumberSchema extends Schema<number> {
|
|
4
4
|
readonly value: number | null;
|
|
5
5
|
readonly min: number | null;
|
|
6
6
|
readonly max: number | null;
|
|
7
7
|
readonly step: number | null;
|
|
8
|
-
constructor({ value, min, max, step, ...rest }:
|
|
8
|
+
constructor({ value, min, max, step, ...rest }: SchemaOptions & {
|
|
9
9
|
readonly value?: number | null;
|
|
10
10
|
readonly min?: number | null;
|
|
11
11
|
readonly max?: number | null;
|
package/schema/Schema.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { Validatable } from "../util/validate.js";
|
|
2
|
+
/** Options allowed by a `Schema` instance. */
|
|
3
|
+
export declare type SchemaOptions = {
|
|
4
|
+
/** Title of the schema, e.g. for using as the title of a corresponding field. */
|
|
5
|
+
readonly title?: string;
|
|
6
|
+
/** Description of the schema, e.g. for using as a description in a corresponding field. */
|
|
7
|
+
readonly description?: string;
|
|
8
|
+
/** Placeholder of the schema, e.g. for using as a placeholder in a corresponding field. */
|
|
9
|
+
readonly placeholder?: string;
|
|
10
|
+
};
|
|
2
11
|
/**
|
|
3
12
|
* Schema is an object instance with a `validate()` method.
|
|
4
13
|
* - Type `T` represents the type of value `validate()` returns.
|
|
@@ -13,14 +22,7 @@ export declare abstract class Schema<T extends unknown = unknown> implements Val
|
|
|
13
22
|
readonly placeholder: string;
|
|
14
23
|
/** Default value. */
|
|
15
24
|
readonly value: unknown;
|
|
16
|
-
constructor({ title, description, placeholder
|
|
17
|
-
/** Title of the schema, e.g. for using as the title of a corresponding field. */
|
|
18
|
-
readonly title?: string;
|
|
19
|
-
/** Description of the schema, e.g. for using as a description in a corresponding field. */
|
|
20
|
-
readonly description?: string;
|
|
21
|
-
/** Placeholder of the schema, e.g. for using as a placeholder in a corresponding field. */
|
|
22
|
-
readonly placeholder?: string;
|
|
23
|
-
});
|
|
25
|
+
constructor({ title, description, placeholder }: SchemaOptions);
|
|
24
26
|
/** Every schema must implement a `validate()` method. */
|
|
25
27
|
abstract validate(unsafeValue: unknown): T;
|
|
26
28
|
}
|
package/schema/Schema.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* - `validate()` returns `Invalid` if value was not valid.
|
|
5
5
|
*/
|
|
6
6
|
export class Schema {
|
|
7
|
-
constructor({ title = "", description = "", placeholder = ""
|
|
7
|
+
constructor({ title = "", description = "", placeholder = "" }) {
|
|
8
8
|
this.title = title;
|
|
9
9
|
this.description = description;
|
|
10
10
|
this.placeholder = placeholder;
|
package/schema/StringSchema.d.ts
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import { Schema } from "./Schema.js";
|
|
1
|
+
import { Schema, SchemaOptions } from "./Schema.js";
|
|
2
2
|
/** `type=""` prop for HTML `<input />` tags that are relevant for strings. */
|
|
3
3
|
export declare type HtmlInputType = "text" | "password" | "color" | "date" | "email" | "number" | "tel" | "search" | "url";
|
|
4
4
|
/** Function that sanitizes a string. */
|
|
5
5
|
export declare type Sanitizer = (str: string) => string;
|
|
6
|
+
/** Options for `StringSchema` */
|
|
7
|
+
export declare type StringSchemaOptions = SchemaOptions & {
|
|
8
|
+
readonly value?: string;
|
|
9
|
+
readonly type?: HtmlInputType;
|
|
10
|
+
readonly min?: number;
|
|
11
|
+
readonly max?: number | null;
|
|
12
|
+
readonly match?: RegExp | null;
|
|
13
|
+
readonly sanitizer?: Sanitizer | null;
|
|
14
|
+
readonly multiline?: boolean;
|
|
15
|
+
};
|
|
6
16
|
/**
|
|
7
17
|
* Schema that defines a valid string.
|
|
8
18
|
*
|
|
@@ -31,15 +41,7 @@ export declare class StringSchema extends Schema<string> {
|
|
|
31
41
|
readonly match: RegExp | null;
|
|
32
42
|
readonly sanitizer: Sanitizer | null;
|
|
33
43
|
readonly multiline: boolean;
|
|
34
|
-
constructor({ value, type, min, max, match, sanitizer, multiline, ...rest }:
|
|
35
|
-
readonly value?: string;
|
|
36
|
-
readonly type?: HtmlInputType;
|
|
37
|
-
readonly min?: number;
|
|
38
|
-
readonly max?: number | null;
|
|
39
|
-
readonly match?: RegExp | null;
|
|
40
|
-
readonly sanitizer?: Sanitizer | null;
|
|
41
|
-
readonly multiline?: boolean;
|
|
42
|
-
});
|
|
44
|
+
constructor({ value, type, min, max, match, sanitizer, multiline, ...rest }: StringSchemaOptions);
|
|
43
45
|
validate(unsafeValue?: unknown): string;
|
|
44
46
|
/**
|
|
45
47
|
* Clean a string by removing characters that aren't digits.
|
package/schema/index.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ export * from "./BooleanSchema.js";
|
|
|
5
5
|
export * from "./ColorSchema.js";
|
|
6
6
|
export * from "./DataSchema.js";
|
|
7
7
|
export * from "./DateSchema.js";
|
|
8
|
+
export * from "./DictionarySchema.js";
|
|
8
9
|
export * from "./EmailSchema.js";
|
|
9
10
|
export * from "./KeySchema.js";
|
|
10
11
|
export * from "./LinkSchema.js";
|
|
11
12
|
export * from "./NumberSchema.js";
|
|
12
|
-
export * from "./ObjectSchema.js";
|
|
13
13
|
export * from "./OptionalSchema.js";
|
|
14
14
|
export * from "./PhoneSchema.js";
|
|
15
15
|
export * from "./RequiredSchema.js";
|
package/schema/index.js
CHANGED
|
@@ -5,11 +5,11 @@ export * from "./BooleanSchema.js";
|
|
|
5
5
|
export * from "./ColorSchema.js";
|
|
6
6
|
export * from "./DataSchema.js";
|
|
7
7
|
export * from "./DateSchema.js";
|
|
8
|
+
export * from "./DictionarySchema.js";
|
|
8
9
|
export * from "./EmailSchema.js";
|
|
9
10
|
export * from "./KeySchema.js";
|
|
10
11
|
export * from "./LinkSchema.js";
|
|
11
12
|
export * from "./NumberSchema.js";
|
|
12
|
-
export * from "./ObjectSchema.js";
|
|
13
13
|
export * from "./OptionalSchema.js";
|
|
14
14
|
export * from "./PhoneSchema.js";
|
|
15
15
|
export * from "./RequiredSchema.js";
|