shelving 1.157.2 → 1.158.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/Endpoint.d.ts +21 -21
- package/api/Endpoint.js +14 -13
- package/package.json +1 -1
- package/schema/ArraySchema.d.ts +3 -4
- package/schema/DataSchema.d.ts +8 -9
- package/schema/DataSchema.js +7 -5
- package/schema/DictionarySchema.d.ts +3 -4
- package/schema/Schema.d.ts +8 -0
- package/schema/Schema.js +9 -0
- package/schema/ThroughSchema.d.ts +3 -4
- package/util/hydrate.js +11 -5
- package/util/transform.d.ts +10 -21
- package/util/transform.js +9 -4
- package/util/validate.d.ts +0 -3
- package/util/validate.js +0 -9
package/api/Endpoint.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { type Schema } from "../schema/Schema.js";
|
|
1
2
|
import type { AbsolutePath } from "../util/path.js";
|
|
2
|
-
import { type Validator } from "../util/validate.js";
|
|
3
3
|
import type { EndpointCallback, EndpointHandler } from "./util.js";
|
|
4
4
|
/** Types for an HTTP request or response that does something. */
|
|
5
5
|
export type EndpointMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
@@ -8,8 +8,8 @@ export type EndpointMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
|
8
8
|
*
|
|
9
9
|
* @param method The method of the resource, e.g. `GET`
|
|
10
10
|
* @param path The path of the resource optionally including `{placeholder}` values, e.g. `/patient/{id}`
|
|
11
|
-
* @param payload A `
|
|
12
|
-
* @param result A `
|
|
11
|
+
* @param payload A `Schema` for the payload of the resource.
|
|
12
|
+
* @param result A `Schema` for the result of the resource.
|
|
13
13
|
*/
|
|
14
14
|
export declare class Endpoint<P, R> {
|
|
15
15
|
/** Endpoint method. */
|
|
@@ -17,10 +17,10 @@ export declare class Endpoint<P, R> {
|
|
|
17
17
|
/** Endpoint path, e.g. `/patient/{id}` */
|
|
18
18
|
readonly path: AbsolutePath;
|
|
19
19
|
/** Payload validator. */
|
|
20
|
-
readonly payload:
|
|
20
|
+
readonly payload: Schema<P>;
|
|
21
21
|
/** Result validator. */
|
|
22
|
-
readonly result:
|
|
23
|
-
constructor(method: EndpointMethod, path: AbsolutePath, payload:
|
|
22
|
+
readonly result: Schema<R>;
|
|
23
|
+
constructor(method: EndpointMethod, path: AbsolutePath, payload: Schema<P>, result: Schema<R>);
|
|
24
24
|
/**
|
|
25
25
|
* Return an `EndpointHandler` for this endpoint.
|
|
26
26
|
*
|
|
@@ -46,34 +46,34 @@ export type EndpointType<X extends Endpoint<unknown, unknown>> = X extends Endpo
|
|
|
46
46
|
* Represent a GET request to a specified path, with validated payload and return types.
|
|
47
47
|
* "The GET method requests a representation of the specified resource. Requests using GET should only retrieve data and should not contain a request content."
|
|
48
48
|
*/
|
|
49
|
-
export declare function GET<P, R>(path: AbsolutePath, payload?:
|
|
50
|
-
export declare function GET<P>(path: AbsolutePath, payload:
|
|
51
|
-
export declare function GET<R>(path: AbsolutePath, payload: undefined, result:
|
|
49
|
+
export declare function GET<P, R>(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
|
|
50
|
+
export declare function GET<P>(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>;
|
|
51
|
+
export declare function GET<R>(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
|
|
52
52
|
/**
|
|
53
53
|
* Represent a POST request to a specified path, with validated payload and return types.
|
|
54
54
|
* "The POST method submits an entity to the specified resource, often causing a change in state or side effects on the server.
|
|
55
55
|
*/
|
|
56
|
-
export declare function POST<P, R>(path: AbsolutePath, payload?:
|
|
57
|
-
export declare function POST<P>(path: AbsolutePath, payload:
|
|
58
|
-
export declare function POST<R>(path: AbsolutePath, payload: undefined, result:
|
|
56
|
+
export declare function POST<P, R>(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
|
|
57
|
+
export declare function POST<P>(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>;
|
|
58
|
+
export declare function POST<R>(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
|
|
59
59
|
/**
|
|
60
60
|
* Represent a PUT request to a specified path, with validated payload and return types.
|
|
61
61
|
* "The PUT method replaces all current representations of the target resource with the request content."
|
|
62
62
|
*/
|
|
63
|
-
export declare function PUT<P, R>(path: AbsolutePath, payload?:
|
|
64
|
-
export declare function PUT<P>(path: AbsolutePath, payload:
|
|
65
|
-
export declare function PUT<R>(path: AbsolutePath, payload: undefined, result:
|
|
63
|
+
export declare function PUT<P, R>(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
|
|
64
|
+
export declare function PUT<P>(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>;
|
|
65
|
+
export declare function PUT<R>(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
|
|
66
66
|
/**
|
|
67
67
|
* Represent a PATCH request to a specified path, with validated payload and return types.
|
|
68
68
|
* "The PATCH method applies partial modifications to a resource."
|
|
69
69
|
*/
|
|
70
|
-
export declare function PATCH<P, R>(path: AbsolutePath, payload?:
|
|
71
|
-
export declare function PATCH<P>(path: AbsolutePath, payload:
|
|
72
|
-
export declare function PATCH<R>(path: AbsolutePath, payload: undefined, result:
|
|
70
|
+
export declare function PATCH<P, R>(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
|
|
71
|
+
export declare function PATCH<P>(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>;
|
|
72
|
+
export declare function PATCH<R>(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
|
|
73
73
|
/**
|
|
74
74
|
* Represent a DELETE request to a specified path, with validated payload and return types.
|
|
75
75
|
* "The DELETE method deletes the specified resource."
|
|
76
76
|
*/
|
|
77
|
-
export declare function DELETE<P, R>(path: AbsolutePath, payload?:
|
|
78
|
-
export declare function DELETE<P>(path: AbsolutePath, payload:
|
|
79
|
-
export declare function DELETE<R>(path: AbsolutePath, payload: undefined, result:
|
|
77
|
+
export declare function DELETE<P, R>(path: AbsolutePath, payload?: Schema<P>, result?: Schema<R>): Endpoint<P, R>;
|
|
78
|
+
export declare function DELETE<P>(path: AbsolutePath, payload: Schema<P>): Endpoint<P, undefined>;
|
|
79
|
+
export declare function DELETE<R>(path: AbsolutePath, payload: undefined, result: Schema<R>): Endpoint<undefined, R>;
|
package/api/Endpoint.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import { UNDEFINED } from "../schema/Schema.js";
|
|
1
2
|
import { getResponse } from "../util/http.js";
|
|
2
|
-
import {
|
|
3
|
+
import { getValid } from "../util/validate.js";
|
|
3
4
|
/**
|
|
4
5
|
* An abstract API resource definition, used to specify types for e.g. serverless functions.
|
|
5
6
|
*
|
|
6
7
|
* @param method The method of the resource, e.g. `GET`
|
|
7
8
|
* @param path The path of the resource optionally including `{placeholder}` values, e.g. `/patient/{id}`
|
|
8
|
-
* @param payload A `
|
|
9
|
-
* @param result A `
|
|
9
|
+
* @param payload A `Schema` for the payload of the resource.
|
|
10
|
+
* @param result A `Schema` for the result of the resource.
|
|
10
11
|
*/
|
|
11
12
|
export class Endpoint {
|
|
12
13
|
/** Endpoint method. */
|
|
@@ -53,18 +54,18 @@ export class Endpoint {
|
|
|
53
54
|
return `${this.method} ${this.path}`;
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
|
-
export function GET(path, payload, result) {
|
|
57
|
-
return new Endpoint("GET", path, payload
|
|
57
|
+
export function GET(path, payload = UNDEFINED, result = UNDEFINED) {
|
|
58
|
+
return new Endpoint("GET", path, payload, result);
|
|
58
59
|
}
|
|
59
|
-
export function POST(path, payload, result) {
|
|
60
|
-
return new Endpoint("POST", path, payload
|
|
60
|
+
export function POST(path, payload = UNDEFINED, result = UNDEFINED) {
|
|
61
|
+
return new Endpoint("POST", path, payload, result);
|
|
61
62
|
}
|
|
62
|
-
export function PUT(path, payload, result) {
|
|
63
|
-
return new Endpoint("PUT", path, payload
|
|
63
|
+
export function PUT(path, payload = UNDEFINED, result = UNDEFINED) {
|
|
64
|
+
return new Endpoint("PUT", path, payload, result);
|
|
64
65
|
}
|
|
65
|
-
export function PATCH(path, payload, result) {
|
|
66
|
-
return new Endpoint("PATCH", path, payload
|
|
66
|
+
export function PATCH(path, payload = UNDEFINED, result = UNDEFINED) {
|
|
67
|
+
return new Endpoint("PATCH", path, payload, result);
|
|
67
68
|
}
|
|
68
|
-
export function DELETE(path, payload, result) {
|
|
69
|
-
return new Endpoint("DELETE", path, payload
|
|
69
|
+
export function DELETE(path, payload = UNDEFINED, result = UNDEFINED) {
|
|
70
|
+
return new Endpoint("DELETE", path, payload, result);
|
|
70
71
|
}
|
package/package.json
CHANGED
package/schema/ArraySchema.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import type { ImmutableArray } from "../util/array.js";
|
|
2
|
-
import type { Validator } from "../util/validate.js";
|
|
3
2
|
import type { SchemaOptions } from "./Schema.js";
|
|
4
3
|
import { Schema } from "./Schema.js";
|
|
5
4
|
/** Allowed options for `ArraySchema` */
|
|
6
5
|
export interface ArraySchemaOptions<T> extends SchemaOptions {
|
|
7
6
|
readonly value?: ImmutableArray;
|
|
8
|
-
readonly items:
|
|
7
|
+
readonly items: Schema<T>;
|
|
9
8
|
readonly min?: number;
|
|
10
9
|
readonly max?: number;
|
|
11
10
|
readonly unique?: boolean;
|
|
@@ -39,7 +38,7 @@ export interface ArraySchemaOptions<T> extends SchemaOptions {
|
|
|
39
38
|
*/
|
|
40
39
|
export declare class ArraySchema<T> extends Schema<ImmutableArray<T>> {
|
|
41
40
|
readonly value: ImmutableArray;
|
|
42
|
-
readonly items:
|
|
41
|
+
readonly items: Schema<T>;
|
|
43
42
|
readonly unique: boolean;
|
|
44
43
|
readonly min: number;
|
|
45
44
|
readonly max: number;
|
|
@@ -47,4 +46,4 @@ export declare class ArraySchema<T> extends Schema<ImmutableArray<T>> {
|
|
|
47
46
|
validate(unsafeValue?: unknown): ImmutableArray<T>;
|
|
48
47
|
}
|
|
49
48
|
/** Valid array with specifed items. */
|
|
50
|
-
export declare const ARRAY: <T>(items:
|
|
49
|
+
export declare const ARRAY: <T>(items: Schema<T>) => ArraySchema<T>;
|
package/schema/DataSchema.d.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import type { Data, Database } from "../util/data.js";
|
|
2
2
|
import type { Identifier, Item } from "../util/item.js";
|
|
3
|
-
import type { Validator, Validators } from "../util/validate.js";
|
|
4
3
|
import type { NullableSchema } from "./NullableSchema.js";
|
|
5
|
-
import type { SchemaOptions } from "./Schema.js";
|
|
4
|
+
import type { SchemaOptions, Schemas } from "./Schema.js";
|
|
6
5
|
import { Schema } from "./Schema.js";
|
|
7
6
|
/** Allowed options for `PropsSchema` (a schema that has props). */
|
|
8
7
|
export interface DataSchemaOptions<T extends Data> extends SchemaOptions {
|
|
9
|
-
readonly id?:
|
|
10
|
-
readonly props:
|
|
8
|
+
readonly id?: Schema<string>;
|
|
9
|
+
readonly props: Schemas<T>;
|
|
11
10
|
readonly value?: Partial<T> | undefined;
|
|
12
11
|
}
|
|
13
12
|
/** Validate a data object. */
|
|
14
13
|
export declare class DataSchema<T extends Data> extends Schema<unknown> {
|
|
15
14
|
readonly value: Partial<T>;
|
|
16
|
-
readonly props:
|
|
15
|
+
readonly props: Schemas<T>;
|
|
17
16
|
constructor({ props, title, value, ...options }: DataSchemaOptions<T>);
|
|
18
17
|
validate(unsafeValue?: unknown): T;
|
|
19
18
|
}
|
|
@@ -22,10 +21,10 @@ export type DataSchemas<T extends Database> = {
|
|
|
22
21
|
[K in keyof T]: DataSchema<T[K]>;
|
|
23
22
|
};
|
|
24
23
|
/** Create a `DataSchema` for a set of properties. */
|
|
25
|
-
export declare const DATA: <T extends Data>(props:
|
|
24
|
+
export declare const DATA: <T extends Data>(props: Schemas<T>) => DataSchema<T>;
|
|
26
25
|
/** Valid data object with specifed properties, or `null` */
|
|
27
|
-
export declare const NULLABLE_DATA: <T extends Data>(props:
|
|
26
|
+
export declare const NULLABLE_DATA: <T extends Data>(props: Schemas<T>) => NullableSchema<T>;
|
|
28
27
|
/** Create a `DataSchema` that validates partially, i.e. properties can be their value, or `undefined` */
|
|
29
|
-
export declare function PARTIAL<T extends Data>(source:
|
|
28
|
+
export declare function PARTIAL<T extends Data>(source: Schemas<T> | DataSchema<T>): DataSchema<Partial<T>>;
|
|
30
29
|
/** Create a `DataSchema` that validates a data item, i.e. it has a string or number `.id` identifier property. */
|
|
31
|
-
export declare function ITEM<I extends Identifier, T extends Data>(id:
|
|
30
|
+
export declare function ITEM<I extends Identifier, T extends Data>(id: Schema<I>, schemas: Schemas<T> | DataSchema<T>): DataSchema<Item<I, T>>;
|
package/schema/DataSchema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ValueFeedback } from "../feedback/Feedback.js";
|
|
2
2
|
import { isData } from "../util/data.js";
|
|
3
|
-
import {
|
|
3
|
+
import { mapProps } from "../util/transform.js";
|
|
4
4
|
import { validateData } from "../util/validate.js";
|
|
5
5
|
import { NULLABLE } from "./NullableSchema.js";
|
|
6
6
|
import { OPTIONAL } from "./OptionalSchema.js";
|
|
@@ -22,16 +22,18 @@ export class DataSchema extends Schema {
|
|
|
22
22
|
export const DATA = (props) => new DataSchema({ props });
|
|
23
23
|
/** Valid data object with specifed properties, or `null` */
|
|
24
24
|
export const NULLABLE_DATA = (props) => NULLABLE(new DataSchema({ props }));
|
|
25
|
-
/** Create a `DataSchema` that validates partially, i.e. properties can be their value, or `undefined` */
|
|
26
25
|
export function PARTIAL(source) {
|
|
27
26
|
const props = source instanceof DataSchema ? source.props : source;
|
|
28
27
|
return new DataSchema({
|
|
29
|
-
props:
|
|
28
|
+
props: mapProps(props, _optionalProp),
|
|
30
29
|
});
|
|
31
30
|
}
|
|
31
|
+
function _optionalProp([, v]) {
|
|
32
|
+
return OPTIONAL(v);
|
|
33
|
+
}
|
|
32
34
|
/** Create a `DataSchema` that validates a data item, i.e. it has a string or number `.id` identifier property. */
|
|
33
|
-
export function ITEM(id,
|
|
34
|
-
const props =
|
|
35
|
+
export function ITEM(id, schemas) {
|
|
36
|
+
const props = schemas instanceof DataSchema ? schemas.props : schemas;
|
|
35
37
|
return new DataSchema({
|
|
36
38
|
props: { id, ...props },
|
|
37
39
|
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { ImmutableDictionary } from "../util/dictionary.js";
|
|
2
|
-
import type { Validator } from "../util/validate.js";
|
|
3
2
|
import type { SchemaOptions } from "./Schema.js";
|
|
4
3
|
import { Schema } from "./Schema.js";
|
|
5
4
|
/** Allowed options for `DictionarySchema` */
|
|
6
5
|
export interface DictionarySchemaOptions<T> extends SchemaOptions {
|
|
7
|
-
readonly items:
|
|
6
|
+
readonly items: Schema<T>;
|
|
8
7
|
readonly value?: ImmutableDictionary | undefined;
|
|
9
8
|
readonly min?: number | undefined;
|
|
10
9
|
readonly max?: number | undefined;
|
|
@@ -12,11 +11,11 @@ export interface DictionarySchemaOptions<T> extends SchemaOptions {
|
|
|
12
11
|
/** Validate a dictionary object (whose props are all the same with string keys). */
|
|
13
12
|
export declare class DictionarySchema<T> extends Schema<ImmutableDictionary<T>> {
|
|
14
13
|
readonly value: ImmutableDictionary;
|
|
15
|
-
readonly items:
|
|
14
|
+
readonly items: Schema<T>;
|
|
16
15
|
readonly min: number;
|
|
17
16
|
readonly max: number;
|
|
18
17
|
constructor({ items, min, max, title, value, ...options }: DictionarySchemaOptions<T>);
|
|
19
18
|
validate(unsafeValue?: unknown): ImmutableDictionary<T>;
|
|
20
19
|
}
|
|
21
20
|
/** Valid dictionary object with specifed items. */
|
|
22
|
-
export declare const DICTIONARY: <T>(items:
|
|
21
|
+
export declare const DICTIONARY: <T>(items: Schema<T>) => DictionarySchema<T>;
|
package/schema/Schema.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Data } from "../util/data.js";
|
|
1
2
|
import type { Validator } from "../util/validate.js";
|
|
2
3
|
/** Options allowed by a `Schema` instance. */
|
|
3
4
|
export type SchemaOptions = {
|
|
@@ -28,3 +29,10 @@ export declare abstract class Schema<T = unknown> implements Validator<T> {
|
|
|
28
29
|
/** Every schema must implement a `validate()` method. */
|
|
29
30
|
abstract validate(unsafeValue: unknown): T;
|
|
30
31
|
}
|
|
32
|
+
/** A set of named schemas in `{ name: schema }` format. */
|
|
33
|
+
export type Schemas<T extends Data = Data> = {
|
|
34
|
+
readonly [K in keyof T]: Schema<T[K]>;
|
|
35
|
+
};
|
|
36
|
+
export declare const UNKNOWN: Schema<unknown>;
|
|
37
|
+
export declare const UNDEFINED: Schema<undefined>;
|
|
38
|
+
export declare const NULL: Schema<null>;
|
package/schema/Schema.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { PASSTHROUGH } from "../util/function.js";
|
|
2
|
+
import { getNull } from "../util/null.js";
|
|
3
|
+
import { getUndefined } from "../util/undefined.js";
|
|
1
4
|
/**
|
|
2
5
|
* Schema is an object instance with a `validate()` method.
|
|
3
6
|
* - Type `T` represents the type of value `validate()` returns.
|
|
@@ -19,3 +22,9 @@ export class Schema {
|
|
|
19
22
|
this.value = value;
|
|
20
23
|
}
|
|
21
24
|
}
|
|
25
|
+
// Unknown validator always passes through its input value as `unknown`
|
|
26
|
+
export const UNKNOWN = { title: "", description: "", placeholder: "", value: undefined, validate: PASSTHROUGH };
|
|
27
|
+
// Undefined validator always returns `undefined`
|
|
28
|
+
export const UNDEFINED = { ...UNKNOWN, validate: getUndefined };
|
|
29
|
+
// Null validator always returns `null`
|
|
30
|
+
export const NULL = { ...UNKNOWN, validate: getNull };
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import type { Sourceable } from "../util/source.js";
|
|
2
|
-
import type { Validator } from "../util/validate.js";
|
|
3
2
|
import type { SchemaOptions } from "./Schema.js";
|
|
4
3
|
import { Schema } from "./Schema.js";
|
|
5
4
|
/** Allowed options for `ThroughSchema` */
|
|
6
5
|
export interface ThroughSchemaOptions<T> extends SchemaOptions {
|
|
7
|
-
source:
|
|
6
|
+
source: Schema<T>;
|
|
8
7
|
}
|
|
9
8
|
/** Schema that passes through to a source schema. */
|
|
10
|
-
export declare abstract class ThroughSchema<T> extends Schema<T> implements Sourceable<
|
|
11
|
-
readonly source:
|
|
9
|
+
export declare abstract class ThroughSchema<T> extends Schema<T> implements Sourceable<Schema<T>> {
|
|
10
|
+
readonly source: Schema<T>;
|
|
12
11
|
constructor({ source, ...options }: ThroughSchemaOptions<T>);
|
|
13
12
|
validate(unsafeValue: unknown): T;
|
|
14
13
|
}
|
package/util/hydrate.js
CHANGED
|
@@ -5,7 +5,7 @@ import { isMap } from "./map.js";
|
|
|
5
5
|
import { getProps, getPrototype, isObject, isPlainObject } from "./object.js";
|
|
6
6
|
import { isSet } from "./set.js";
|
|
7
7
|
import { isString } from "./string.js";
|
|
8
|
-
import { mapArray,
|
|
8
|
+
import { mapArray, mapProps } from "./transform.js";
|
|
9
9
|
/** Is an unknown value a dehydrated object with a `$type` key. */
|
|
10
10
|
function _isDehydrated(value) {
|
|
11
11
|
return isString(value.$type);
|
|
@@ -22,7 +22,7 @@ export function hydrate(value, hydrations) {
|
|
|
22
22
|
return mapArray(value, hydrate, hydrations);
|
|
23
23
|
if (isPlainObject(value)) {
|
|
24
24
|
if (!_isDehydrated(value))
|
|
25
|
-
return
|
|
25
|
+
return mapProps(value, _hydrateProp, hydrations);
|
|
26
26
|
const { $type, $value } = value;
|
|
27
27
|
if ($type === "Map")
|
|
28
28
|
return new Map($value);
|
|
@@ -33,11 +33,14 @@ export function hydrate(value, hydrations) {
|
|
|
33
33
|
// Complex object, check the hydrations list.
|
|
34
34
|
const hydration = hydrations[$type];
|
|
35
35
|
if (hydration)
|
|
36
|
-
return { __proto__: hydration.prototype, ...
|
|
36
|
+
return { __proto__: hydration.prototype, ...mapProps($value, _hydrateProp, hydrations) };
|
|
37
37
|
throw new ValueError(`Cannot hydrate object "${$type}"`, { type: $type, received: $value, caller: hydrate });
|
|
38
38
|
}
|
|
39
39
|
return value;
|
|
40
40
|
}
|
|
41
|
+
function _hydrateProp([, v], hydrations) {
|
|
42
|
+
return hydrate(v, hydrations);
|
|
43
|
+
}
|
|
41
44
|
/**
|
|
42
45
|
* Deeply dehydrate a class instance based on a set of `Hydrations`
|
|
43
46
|
* - Dehydration allows you to pass class instances from a server back to a client.
|
|
@@ -59,13 +62,16 @@ export function dehydrate(value, hydrations) {
|
|
|
59
62
|
if (isDate(value))
|
|
60
63
|
return { $type: "Date", $value: value.getTime() };
|
|
61
64
|
if (isPlainObject(value))
|
|
62
|
-
return
|
|
65
|
+
return mapProps(value, _dehydrateProp, hydrations);
|
|
63
66
|
// Complex object, check the hydrations list.
|
|
64
67
|
const proto = getPrototype(value);
|
|
65
68
|
for (const [$type, hydration] of getProps(hydrations))
|
|
66
69
|
if (proto === hydration.prototype)
|
|
67
|
-
return { $type, $value:
|
|
70
|
+
return { $type, $value: mapProps(value, _dehydrateProp, hydrations) };
|
|
68
71
|
throw new ValueError("Cannot dehydrate object", { received: value, caller: dehydrate });
|
|
69
72
|
}
|
|
70
73
|
return value;
|
|
71
74
|
}
|
|
75
|
+
function _dehydrateProp([, v], hydrations) {
|
|
76
|
+
return dehydrate(v, hydrations);
|
|
77
|
+
}
|
package/util/transform.d.ts
CHANGED
|
@@ -1,32 +1,22 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ImmutableDictionary } from "./dictionary.js";
|
|
1
|
+
import type { ImmutableArray } from "./array.js";
|
|
2
|
+
import type { DictionaryItem, ImmutableDictionary } from "./dictionary.js";
|
|
3
3
|
import type { Entry } from "./entry.js";
|
|
4
4
|
import type { Arguments } from "./function.js";
|
|
5
|
-
import type { ImmutableObject, Value } from "./object.js";
|
|
6
|
-
/** Function that can transform an input value into an output value. */
|
|
7
|
-
export type Transform<I, O, A extends Arguments = []> = (input: I, ...args: A) => O;
|
|
8
|
-
/** Function that can transform an input value into an output value. */
|
|
9
|
-
export type AsyncTransform<I, O, A extends Arguments = []> = (input: I, ...args: A) => O | PromiseLike<O>;
|
|
5
|
+
import type { ImmutableObject, Prop, Value } from "./object.js";
|
|
10
6
|
/** Set of named transforms for a data object (or `undefined` to skip the transform). */
|
|
11
7
|
export type Transforms<I extends ImmutableObject, O extends ImmutableObject, A extends Arguments = []> = {
|
|
12
|
-
readonly [K in keyof I]?:
|
|
8
|
+
readonly [K in keyof I]?: (input: I[K], ...args: A) => O[K];
|
|
13
9
|
};
|
|
14
10
|
/** Modify a set of items using a transform. */
|
|
15
11
|
export declare function mapItems<I, O, A extends Arguments = []>(items: Iterable<I>, transform: (v: I, ...args: A) => O, ...args: A): Iterable<O>;
|
|
16
|
-
export declare function mapItems<I, O, A extends Arguments = []>(items: Iterable<I>, transform: Transform<I, O, A>, ...args: A): Iterable<O>;
|
|
17
12
|
/** Modify the items of an array using a transform. */
|
|
18
|
-
export declare function mapArray<T extends ImmutableArray>(arr: T, transform: Transform<ArrayItem<T>, ArrayItem<T>>): T;
|
|
19
13
|
export declare function mapArray<I, O, A extends Arguments = []>(arr: Iterable<I>, transform: (v: I, ...args: A) => O, ...args: A): ImmutableArray<O>;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export declare function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export declare function mapDictionary<I, O, A extends Arguments = []>(dictionary: ImmutableDictionary<I>, transform: (v: I, ...args: A) => O, ...args: A): ImmutableDictionary<O>;
|
|
27
|
-
export declare function mapDictionary<I, O, A extends Arguments = []>(dictionary: ImmutableDictionary<I>, transform: Transform<I, O, A>, ...args: A): ImmutableDictionary<O>;
|
|
28
|
-
/** Modify the values of a set of entries using a transform. */
|
|
29
|
-
export declare function mapEntries<K, I, O, A extends Arguments = []>(entries: Iterable<Entry<K, I>>, transform: Transform<I, O, A>, ...args: A): Iterable<Entry<K, O>>;
|
|
14
|
+
/** Modify the _values_ of the props of an object using a transform. */
|
|
15
|
+
export declare function mapProps<I extends ImmutableObject, O extends ImmutableObject, A extends Arguments = []>(obj: I, transform: (prop: Prop<I>, ...args: A) => Value<O>, ...args: A): O;
|
|
16
|
+
/** Modify the _values_ of a dictionary using a transform. */
|
|
17
|
+
export declare function mapDictionary<I, O, A extends Arguments = []>(dictionary: ImmutableDictionary<I>, transform: (item: DictionaryItem<I>, ...args: A) => O, ...args: A): ImmutableDictionary<O>;
|
|
18
|
+
/** Modify the _values_ of a set of entries using a transform. */
|
|
19
|
+
export declare function mapEntries<K, I, O, A extends Arguments = []>(entries: Iterable<Entry<K, I>>, transform: (entry: Entry<K, I>, ...args: A) => O, ...args: A): Iterable<Entry<K, O>>;
|
|
30
20
|
/**
|
|
31
21
|
* Transform an object using a set of named transforms.
|
|
32
22
|
*
|
|
@@ -38,4 +28,3 @@ export declare function transformObject<I extends ImmutableObject, O extends Imm
|
|
|
38
28
|
export declare function transformObject<I extends ImmutableObject, O extends ImmutableObject, A extends Arguments = []>(obj: I | Partial<I>, transforms: Transforms<I, O | Partial<O>, A>, ...args: A): Partial<O>;
|
|
39
29
|
/** Transform items in a sequence as they are yielded using a (potentially async) transform. */
|
|
40
30
|
export declare function mapSequence<I, O, A extends Arguments = []>(sequence: AsyncIterable<I>, transform: (input: I, ...args: A) => O | PromiseLike<O>, ...args: A): AsyncIterable<O>;
|
|
41
|
-
export declare function mapSequence<I, O, A extends Arguments = []>(sequence: AsyncIterable<I>, transform: AsyncTransform<I, O, A>, ...args: A): AsyncIterable<O>;
|
package/util/transform.js
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import { getDictionaryItems } from "./dictionary.js";
|
|
2
2
|
import { getProps } from "./object.js";
|
|
3
|
+
/** Modify a set of items using a transform. */
|
|
3
4
|
export function* mapItems(items, transform, ...args) {
|
|
4
5
|
for (const item of items)
|
|
5
6
|
yield transform(item, ...args);
|
|
6
7
|
}
|
|
8
|
+
/** Modify the items of an array using a transform. */
|
|
7
9
|
export function mapArray(arr, transform, ...args) {
|
|
8
10
|
return Array.from(mapItems(arr, transform, ...args));
|
|
9
11
|
}
|
|
10
|
-
|
|
12
|
+
/** Modify the _values_ of the props of an object using a transform. */
|
|
13
|
+
export function mapProps(obj, transform, ...args) {
|
|
11
14
|
return Object.fromEntries(mapEntries(getProps(obj), transform, ...args));
|
|
12
15
|
}
|
|
16
|
+
/** Modify the _values_ of a dictionary using a transform. */
|
|
13
17
|
export function mapDictionary(dictionary, transform, ...args) {
|
|
14
18
|
return Object.fromEntries(mapEntries(getDictionaryItems(dictionary), transform, ...args));
|
|
15
19
|
}
|
|
16
|
-
/** Modify the
|
|
20
|
+
/** Modify the _values_ of a set of entries using a transform. */
|
|
17
21
|
export function* mapEntries(entries, transform, ...args) {
|
|
18
|
-
for (const
|
|
19
|
-
yield [
|
|
22
|
+
for (const e of entries)
|
|
23
|
+
yield [e[0], transform(e, ...args)];
|
|
20
24
|
}
|
|
21
25
|
export function transformObject(input, transforms, ...args) {
|
|
22
26
|
let changed = false;
|
|
@@ -37,6 +41,7 @@ export function transformObject(input, transforms, ...args) {
|
|
|
37
41
|
}
|
|
38
42
|
return changed ? output : input;
|
|
39
43
|
}
|
|
44
|
+
/** Transform items in a sequence as they are yielded using a (potentially async) transform. */
|
|
40
45
|
export async function* mapSequence(sequence, transform, ...args) {
|
|
41
46
|
for await (const item of sequence)
|
|
42
47
|
yield transform(item, ...args);
|
package/util/validate.d.ts
CHANGED
|
@@ -64,6 +64,3 @@ export declare function validateDictionary<T>(unsafeDictionary: ImmutableDiction
|
|
|
64
64
|
*/
|
|
65
65
|
export declare function validateData<T extends Data>(unsafeData: Data, validators: Validators<T>, partial: true): DeepPartial<T>;
|
|
66
66
|
export declare function validateData<T extends Data>(unsafeData: Data, validators: Validators<T>, partial?: false): T;
|
|
67
|
-
export declare const UNDEFINED: Validator<undefined>;
|
|
68
|
-
export declare const NULL: Validator<null>;
|
|
69
|
-
export declare const UNKNOWN: Validator<unknown>;
|
package/util/validate.js
CHANGED
|
@@ -4,10 +4,7 @@ import { isArray } from "./array.js";
|
|
|
4
4
|
import { getDataKeys, getDataProps } from "./data.js";
|
|
5
5
|
import { getDictionaryItems } from "./dictionary.js";
|
|
6
6
|
import { getNamedMessage } from "./error.js";
|
|
7
|
-
import { PASSTHROUGH } from "./function.js";
|
|
8
7
|
import { isIterable } from "./iterate.js";
|
|
9
|
-
import { getNull } from "./null.js";
|
|
10
|
-
import { getUndefined } from "./undefined.js";
|
|
11
8
|
/** Get value that validates against a given `Validator`, or throw `ValueError` */
|
|
12
9
|
export function getValid(value, validator, ErrorConstructor = ValueError, caller = getValid) {
|
|
13
10
|
try {
|
|
@@ -135,9 +132,3 @@ export function validateData(unsafeData, validators, partial = isDeeplyPartial)
|
|
|
135
132
|
isDeeplyPartial = false;
|
|
136
133
|
}
|
|
137
134
|
}
|
|
138
|
-
// Undefined validator always returns `undefined`
|
|
139
|
-
export const UNDEFINED = { validate: getUndefined };
|
|
140
|
-
// Null validator always returns `null`
|
|
141
|
-
export const NULL = { validate: getNull };
|
|
142
|
-
// Unknown validator always passes through its input value as `unknown`
|
|
143
|
-
export const UNKNOWN = { validate: PASSTHROUGH };
|