shelving 1.150.5 → 1.150.7
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/db/Change.d.ts +3 -3
- package/db/Change.js +3 -3
- package/package.json +1 -1
- package/react/createDataContext.d.ts +3 -3
- package/schema/DateSchema.d.ts +3 -3
- package/schema/TimeSchema.d.ts +3 -3
- package/store/DataStore.d.ts +6 -3
- package/store/DataStore.js +16 -8
- package/store/DictionaryStore.d.ts +3 -3
- package/store/DictionaryStore.js +3 -3
- package/store/PathStore.d.ts +2 -1
- package/store/PathStore.js +7 -4
- package/store/Store.d.ts +0 -2
- package/store/Store.js +0 -4
- package/util/entity.d.ts +3 -3
- package/util/error.d.ts +15 -23
- package/util/error.js +38 -33
- package/util/index.d.ts +0 -1
- package/util/index.js +0 -1
- package/util/link.d.ts +3 -3
- package/util/path.d.ts +2 -2
- package/util/path.js +2 -2
- package/util/string.d.ts +4 -0
- package/util/string.js +8 -0
- package/util/url.d.ts +2 -2
- package/util/url.js +2 -2
- package/util/optional.d.ts +0 -7
- package/util/optional.js +0 -11
package/db/Change.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ImmutableArray } from "../util/array.js";
|
|
2
2
|
import type { DataKey, Database } from "../util/data.js";
|
|
3
3
|
import type { ItemQuery } from "../util/item.js";
|
|
4
|
-
import { type
|
|
4
|
+
import { type Nullish } from "../util/null.js";
|
|
5
5
|
import type { Updates } from "../util/update.js";
|
|
6
6
|
import type { AsyncProvider, Provider } from "./Provider.js";
|
|
7
7
|
/** A change to a database. */
|
|
@@ -68,8 +68,8 @@ export type DatabaseChanges<T extends Database> = ImmutableArray<DatabaseChange<
|
|
|
68
68
|
/** Write a single change to a synchronous provider and return an array of the changes that were written. */
|
|
69
69
|
export declare function writeChange<T extends Database>(provider: Provider<T>, change: DatabaseChange<T>): DatabaseChange<T>;
|
|
70
70
|
/** Write a set of changes to a synchronous provider. */
|
|
71
|
-
export declare function writeChanges<T extends Database>(provider: Provider<T>, ...changes:
|
|
71
|
+
export declare function writeChanges<T extends Database>(provider: Provider<T>, ...changes: Nullish<DatabaseChange<T>>[]): DatabaseChanges<T>;
|
|
72
72
|
/** Write a single change to an asynchronous provider and return the change that was written. */
|
|
73
73
|
export declare function writeAsyncChange<T extends Database>(provider: AsyncProvider<T>, change: DatabaseChange<T>): Promise<DatabaseChange<T>>;
|
|
74
74
|
/** Write a set of changes to an asynchronous provider. */
|
|
75
|
-
export declare function writeAsyncChanges<T extends Database>(provider: AsyncProvider<T>, ...changes:
|
|
75
|
+
export declare function writeAsyncChanges<T extends Database>(provider: AsyncProvider<T>, ...changes: Nullish<DatabaseChange<T>>[]): Promise<DatabaseChanges<T>>;
|
package/db/Change.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { notNullish } from "../util/null.js";
|
|
2
2
|
/** Write a single change to a synchronous provider and return an array of the changes that were written. */
|
|
3
3
|
export function writeChange(provider, change) {
|
|
4
4
|
const { action, collection, id, query } = change;
|
|
@@ -26,7 +26,7 @@ export function writeChange(provider, change) {
|
|
|
26
26
|
}
|
|
27
27
|
/** Write a set of changes to a synchronous provider. */
|
|
28
28
|
export function writeChanges(provider, ...changes) {
|
|
29
|
-
return changes.filter(
|
|
29
|
+
return changes.filter(notNullish).map(change => writeChange(provider, change));
|
|
30
30
|
}
|
|
31
31
|
/** Write a single change to an asynchronous provider and return the change that was written. */
|
|
32
32
|
export async function writeAsyncChange(provider, change) {
|
|
@@ -55,5 +55,5 @@ export async function writeAsyncChange(provider, change) {
|
|
|
55
55
|
}
|
|
56
56
|
/** Write a set of changes to an asynchronous provider. */
|
|
57
57
|
export function writeAsyncChanges(provider, ...changes) {
|
|
58
|
-
return Promise.all(changes.filter(
|
|
58
|
+
return Promise.all(changes.filter(notNullish).map(change => writeAsyncChange(provider, change)));
|
|
59
59
|
}
|
package/package.json
CHANGED
|
@@ -4,14 +4,14 @@ import type { AbstractProvider } from "../db/Provider.js";
|
|
|
4
4
|
import { QueryStore } from "../db/QueryStore.js";
|
|
5
5
|
import type { DataKey, Database } from "../util/data.js";
|
|
6
6
|
import type { ItemQuery } from "../util/item.js";
|
|
7
|
-
import type {
|
|
7
|
+
import type { Nullish } from "../util/null.js";
|
|
8
8
|
export interface DataContext<T extends Database> {
|
|
9
9
|
/** Get an `ItemStore` for the specified collection item in the current `DataProvider` context and subscribe to any changes in it. */
|
|
10
10
|
useItem<K extends DataKey<T>>(this: void, collection: K, id: string): ItemStore<T, K>;
|
|
11
|
-
useItem<K extends DataKey<T>>(this: void, collection:
|
|
11
|
+
useItem<K extends DataKey<T>>(this: void, collection: Nullish<K>, id: Nullish<string>): ItemStore<T, K> | undefined;
|
|
12
12
|
/** Get an `QueryStore` for the specified collection query in the current `DataProvider` context and subscribe to any changes in it. */
|
|
13
13
|
useQuery<K extends DataKey<T>>(this: void, collection: K, query: ItemQuery<T[K]>): QueryStore<T, K>;
|
|
14
|
-
useQuery<K extends DataKey<T>>(this: void, collection:
|
|
14
|
+
useQuery<K extends DataKey<T>>(this: void, collection: Nullish<K>, query: Nullish<ItemQuery<T[K]>>): QueryStore<T, K> | undefined;
|
|
15
15
|
readonly DataContext: ({ children }: {
|
|
16
16
|
children: ReactNode;
|
|
17
17
|
}) => ReactElement;
|
package/schema/DateSchema.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { PossibleDate } from "../util/date.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Nullish } from "../util/null.js";
|
|
3
3
|
import type { SchemaOptions } from "./Schema.js";
|
|
4
4
|
import { Schema } from "./Schema.js";
|
|
5
5
|
/** Allowed options for `DateSchema` */
|
|
6
6
|
export interface DateSchemaOptions extends SchemaOptions {
|
|
7
7
|
readonly value?: PossibleDate | undefined;
|
|
8
|
-
readonly min?:
|
|
9
|
-
readonly max?:
|
|
8
|
+
readonly min?: Nullish<PossibleDate>;
|
|
9
|
+
readonly max?: Nullish<PossibleDate>;
|
|
10
10
|
}
|
|
11
11
|
/** Define a valid date in YMD format, e.g. `2005-09-12` */
|
|
12
12
|
export declare class DateSchema extends Schema<string> {
|
package/schema/TimeSchema.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Nullish } from "../util/null.js";
|
|
2
2
|
import type { PossibleTime } from "../util/time.js";
|
|
3
3
|
import { Time } from "../util/time.js";
|
|
4
4
|
import type { SchemaOptions } from "./Schema.js";
|
|
@@ -6,8 +6,8 @@ import { Schema } from "./Schema.js";
|
|
|
6
6
|
/** Allowed options for `TimeSchama` */
|
|
7
7
|
export interface TimeSchemaOptions extends SchemaOptions {
|
|
8
8
|
readonly value?: PossibleTime | undefined;
|
|
9
|
-
readonly min?:
|
|
10
|
-
readonly max?:
|
|
9
|
+
readonly min?: Nullish<PossibleTime>;
|
|
10
|
+
readonly max?: Nullish<PossibleTime>;
|
|
11
11
|
readonly step?: number | undefined;
|
|
12
12
|
}
|
|
13
13
|
/** Define a valid time in 24h hh:mm:ss.fff format, e.g. `23:59` or `24:00 */
|
package/store/DataStore.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Data, DataKey } from "../util/data.js";
|
|
2
|
+
import type { AnyCaller } from "../util/function.js";
|
|
2
3
|
import type { Updates } from "../util/update.js";
|
|
3
4
|
import { Store } from "./Store.js";
|
|
4
5
|
/** Store a data object. */
|
|
@@ -22,12 +23,14 @@ export declare class OptionalDataStore<T extends Data> extends Store<T | undefin
|
|
|
22
23
|
set data(data: T);
|
|
23
24
|
/** Does the data exist or not? */
|
|
24
25
|
get exists(): boolean;
|
|
26
|
+
/** Require the data for this data store, or throw `RequiredError` if it is not set. */
|
|
27
|
+
require(caller?: AnyCaller): T;
|
|
25
28
|
/** Update several props in this data. */
|
|
26
29
|
update(updates: Updates<T>): void;
|
|
27
30
|
/** Update a single named prop in this data. */
|
|
28
|
-
|
|
31
|
+
get<K extends DataKey<T>>(name: K): T[K];
|
|
29
32
|
/** Update a single named prop in this data. */
|
|
30
|
-
|
|
33
|
+
set<K extends DataKey<T>>(name: K, value: T[K]): void;
|
|
31
34
|
/** Set the data to `undefined`. */
|
|
32
|
-
|
|
35
|
+
delete(): void;
|
|
33
36
|
}
|
package/store/DataStore.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
+
import { getGetter } from "../util/class.js";
|
|
1
3
|
import { withProp } from "../util/object.js";
|
|
2
|
-
import { getRequired } from "../util/optional.js";
|
|
3
4
|
import { updateData } from "../util/update.js";
|
|
4
5
|
import { Store } from "./Store.js";
|
|
5
6
|
/** Store a data object. */
|
|
@@ -29,7 +30,7 @@ export class DataStore extends Store {
|
|
|
29
30
|
export class OptionalDataStore extends Store {
|
|
30
31
|
/** Get current data value of this store (or throw `Promise` that resolves to the next required value). */
|
|
31
32
|
get data() {
|
|
32
|
-
return
|
|
33
|
+
return this.require(getGetter(this, "data"));
|
|
33
34
|
}
|
|
34
35
|
/** Set the data of this store. */
|
|
35
36
|
set data(data) {
|
|
@@ -39,20 +40,27 @@ export class OptionalDataStore extends Store {
|
|
|
39
40
|
get exists() {
|
|
40
41
|
return !!this.value;
|
|
41
42
|
}
|
|
43
|
+
/** Require the data for this data store, or throw `RequiredError` if it is not set. */
|
|
44
|
+
require(caller = this.require) {
|
|
45
|
+
const data = this.value;
|
|
46
|
+
if (!data)
|
|
47
|
+
throw new RequiredError("Data is empty", { caller });
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
42
50
|
/** Update several props in this data. */
|
|
43
51
|
update(updates) {
|
|
44
|
-
this.value = updateData(this.
|
|
52
|
+
this.value = updateData(this.require(this.update), updates);
|
|
45
53
|
}
|
|
46
54
|
/** Update a single named prop in this data. */
|
|
47
|
-
|
|
48
|
-
return this.
|
|
55
|
+
get(name) {
|
|
56
|
+
return this.require(this.get)[name];
|
|
49
57
|
}
|
|
50
58
|
/** Update a single named prop in this data. */
|
|
51
|
-
|
|
52
|
-
this.value = withProp(this.
|
|
59
|
+
set(name, value) {
|
|
60
|
+
this.value = withProp(this.require(this.set), name, value);
|
|
53
61
|
}
|
|
54
62
|
/** Set the data to `undefined`. */
|
|
55
|
-
|
|
63
|
+
delete() {
|
|
56
64
|
this.value = undefined;
|
|
57
65
|
}
|
|
58
66
|
}
|
|
@@ -9,11 +9,11 @@ export declare class DictionaryStore<T> extends Store<ImmutableDictionary<T>> im
|
|
|
9
9
|
/** Set a named entry in this object with a different value. */
|
|
10
10
|
update(updates: Updates<ImmutableDictionary<T>>): void;
|
|
11
11
|
/** Remove a named entry from this object. */
|
|
12
|
-
|
|
12
|
+
deleteItems(...keys: string[]): void;
|
|
13
13
|
/** Get an item in this dictionary. */
|
|
14
|
-
|
|
14
|
+
get(name: string): T | undefined;
|
|
15
15
|
/** Set an item in this dictionary. */
|
|
16
|
-
|
|
16
|
+
set(name: string, value: T): void;
|
|
17
17
|
/** Iterate over the entries of the object. */
|
|
18
18
|
[Symbol.iterator](): Iterator<DictionaryItem<T>>;
|
|
19
19
|
}
|
package/store/DictionaryStore.js
CHANGED
|
@@ -16,15 +16,15 @@ export class DictionaryStore extends Store {
|
|
|
16
16
|
this.value = updateData(this.value, updates);
|
|
17
17
|
}
|
|
18
18
|
/** Remove a named entry from this object. */
|
|
19
|
-
|
|
19
|
+
deleteItems(...keys) {
|
|
20
20
|
this.value = omitDictionaryItems(this.value, ...keys);
|
|
21
21
|
}
|
|
22
22
|
/** Get an item in this dictionary. */
|
|
23
|
-
|
|
23
|
+
get(name) {
|
|
24
24
|
return this.value[name];
|
|
25
25
|
}
|
|
26
26
|
/** Set an item in this dictionary. */
|
|
27
|
-
|
|
27
|
+
set(name, value) {
|
|
28
28
|
this.value = withProp(this.value, name, value);
|
|
29
29
|
}
|
|
30
30
|
/** Iterate over the entries of the object. */
|
package/store/PathStore.d.ts
CHANGED
|
@@ -3,11 +3,12 @@ import { Store } from "./Store.js";
|
|
|
3
3
|
/** Store an absolute path, e.g. `/a/b/c` */
|
|
4
4
|
export declare class PathStore extends Store<AbsolutePath> {
|
|
5
5
|
constructor(path?: string, time?: number);
|
|
6
|
+
get value(): AbsolutePath;
|
|
7
|
+
set value(path: string);
|
|
6
8
|
/** Based on the current store path, is a path active? */
|
|
7
9
|
isActive(path: AbsolutePath): boolean;
|
|
8
10
|
/** Based on the current store path, is a path proud (i.e. a child of the current store path)? */
|
|
9
11
|
isProud(path: AbsolutePath): boolean;
|
|
10
12
|
/** Get an absolute path from a path relative to the current store path. */
|
|
11
13
|
getPath(path: string): AbsolutePath;
|
|
12
|
-
set(path: string): void;
|
|
13
14
|
}
|
package/store/PathStore.js
CHANGED
|
@@ -5,6 +5,13 @@ export class PathStore extends Store {
|
|
|
5
5
|
constructor(path = ".", time) {
|
|
6
6
|
super(requirePath(path), time);
|
|
7
7
|
}
|
|
8
|
+
// Override to clean the path on set.
|
|
9
|
+
get value() {
|
|
10
|
+
return super.value;
|
|
11
|
+
}
|
|
12
|
+
set value(path) {
|
|
13
|
+
super.value = requirePath(path, super.value);
|
|
14
|
+
}
|
|
8
15
|
/** Based on the current store path, is a path active? */
|
|
9
16
|
isActive(path) {
|
|
10
17
|
return isPathActive(this.value, path);
|
|
@@ -17,8 +24,4 @@ export class PathStore extends Store {
|
|
|
17
24
|
getPath(path) {
|
|
18
25
|
return requirePath(path, this.value);
|
|
19
26
|
}
|
|
20
|
-
// Override to clean the path.
|
|
21
|
-
set(path) {
|
|
22
|
-
super.set(requirePath(path, this.value));
|
|
23
|
-
}
|
|
24
27
|
}
|
package/store/Store.d.ts
CHANGED
|
@@ -36,8 +36,6 @@ export declare class Store<T> implements AsyncIterable<T> {
|
|
|
36
36
|
private _starter;
|
|
37
37
|
/** Store is initiated with an initial store. */
|
|
38
38
|
constructor(value: T | typeof NONE, time?: number);
|
|
39
|
-
/** Set the value of the store. */
|
|
40
|
-
set(next: T): void;
|
|
41
39
|
/** Set the value of the store as values are pulled from a sequence. */
|
|
42
40
|
through(sequence: AsyncIterable<T>): AsyncIterable<T>;
|
|
43
41
|
[Symbol.asyncIterator](): AsyncGenerator<T, void, void>;
|
package/store/Store.js
CHANGED
|
@@ -70,10 +70,6 @@ export class Store {
|
|
|
70
70
|
this._value = value;
|
|
71
71
|
this._time = time;
|
|
72
72
|
}
|
|
73
|
-
/** Set the value of the store. */
|
|
74
|
-
set(next) {
|
|
75
|
-
this.value = next;
|
|
76
|
-
}
|
|
77
73
|
/** Set the value of the store as values are pulled from a sequence. */
|
|
78
74
|
async *through(sequence) {
|
|
79
75
|
for await (const value of sequence) {
|
package/util/entity.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnyCaller } from "./function.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Nullish } from "./null.js";
|
|
3
3
|
/** Entity strings combine a type and ID, e.g. `challenge:a1b2c3` */
|
|
4
4
|
export type Entity<T extends string = string> = `${T}:${string}`;
|
|
5
5
|
/** Extract the type from an `Entity` string. */
|
|
@@ -10,8 +10,8 @@ export type EmptyEntity = [type: undefined, id: undefined];
|
|
|
10
10
|
export declare const EMPTY_ENTITY: EmptyEntity;
|
|
11
11
|
/** Split an optional entity tag like `challenge:a1b2c3` into `["challenge", "a1b2c3"]`, or return `EmptyEntity` if the entity was invalid. */
|
|
12
12
|
export declare function getEntity<T extends string>(entity: Entity<T>): [type: T, id: string];
|
|
13
|
-
export declare function getEntity<T extends string>(entity:
|
|
14
|
-
export declare function getEntity(entity:
|
|
13
|
+
export declare function getEntity<T extends string>(entity: Nullish<Entity<T>>): [type: T, id: string] | EmptyEntity;
|
|
14
|
+
export declare function getEntity(entity: Nullish<string>): [type: string, id: string] | EmptyEntity;
|
|
15
15
|
/** Split an entity tag like `challenge:a1b2c3` into `type` and `id`, or throw `RequiredError` if the entity tag was invalid. */
|
|
16
16
|
export declare function requireEntity<T extends string>(entity: Entity<T>, caller?: AnyCaller): [type: T, id: string];
|
|
17
17
|
export declare function requireEntity(entity: string, caller?: AnyCaller): [type: string, id: string];
|
package/util/error.d.ts
CHANGED
|
@@ -1,31 +1,23 @@
|
|
|
1
|
+
import type { ImmutableDictionary } from "./dictionary.js";
|
|
2
|
+
import type { AnyCaller } from "./function.js";
|
|
1
3
|
/** Log an error to the console. */
|
|
2
4
|
export declare function logError(reason: unknown): void;
|
|
3
5
|
/** Is an unknown value an `Error` instance? */
|
|
4
6
|
export declare function isError(v: unknown): v is Error & {
|
|
5
7
|
readonly code?: string | undefined;
|
|
6
8
|
};
|
|
9
|
+
/** Things that can be a message. */
|
|
10
|
+
export type PossibleMessage = {
|
|
11
|
+
message: string;
|
|
12
|
+
} | string;
|
|
13
|
+
/** Return the string message from an unknown value, or return `undefined` if it could not be found. */
|
|
14
|
+
export declare function getMessage(input: unknown): string | undefined;
|
|
15
|
+
/** Require a message from an unknown value, or throw `RequiredError` if it could not be found. */
|
|
16
|
+
export declare function requireMessage(input: PossibleMessage, caller?: AnyCaller): string;
|
|
7
17
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* - The _main_ message is any line(s) that is not a named message.
|
|
13
|
-
*
|
|
14
|
-
* @returns The combined main message(s) found in the full message string.
|
|
18
|
+
* Split a string message into lines, look for prefixes like `name:`, and return a dictionary of those named messages.
|
|
19
|
+
* - Full messages strings can have multiple lines separated by `\n` newline.
|
|
20
|
+
* - Named messages are extracted into their own entries in the dictionary.
|
|
21
|
+
* - Unnamed messages are combined into a single entry with the key `""` (empty string).
|
|
15
22
|
*/
|
|
16
|
-
export declare function
|
|
17
|
-
/**
|
|
18
|
-
* Extract the _named message(s)_ from a full error message string.
|
|
19
|
-
*
|
|
20
|
-
* - Error messages can have multiple lines separated by `\n` newline.
|
|
21
|
-
* - Some lines may be _named messages_ in `name: This is a message` format.
|
|
22
|
-
* - This function extracts any `name: This is a message` lines from the full message string.
|
|
23
|
-
* - Note there may be multiple lines starting with `name:` (in the case where there were multiple errors with that name).
|
|
24
|
-
* - This trims the `name: ` prefix from found messages and rejoins them with `\n` newline.
|
|
25
|
-
*
|
|
26
|
-
* @param fullMessage The full message string which may contain named messages in `name: This is a message` format.
|
|
27
|
-
* @param name The name of the prop to extract the message for.
|
|
28
|
-
*
|
|
29
|
-
* @returns The combined message(s) for the named prop found in the full message string, or an empty string if no messages were found for that prop.
|
|
30
|
-
*/
|
|
31
|
-
export declare function getNamedMessage(fullMessage: string, name: string | number): string;
|
|
23
|
+
export declare function splitMessage(input: PossibleMessage): ImmutableDictionary<string>;
|
package/util/error.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
+
import { isObject } from "./object.js";
|
|
1
3
|
/** Log an error to the console. */
|
|
2
4
|
export function logError(reason) {
|
|
3
5
|
console.error(reason);
|
|
@@ -6,40 +8,43 @@ export function logError(reason) {
|
|
|
6
8
|
export function isError(v) {
|
|
7
9
|
return typeof Error.isError === "function" ? Error.isError(v) : v instanceof Error;
|
|
8
10
|
}
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
let propMessages = "";
|
|
20
|
-
for (const [foundMessage] of fullMessage.matchAll(/^\s*(?!.*: )(.*?)\s*/g))
|
|
21
|
-
if (foundMessage)
|
|
22
|
-
propMessages = propMessages ? `${propMessages}\n${foundMessage}` : foundMessage;
|
|
23
|
-
return propMessages;
|
|
11
|
+
/** Return the string message from an unknown value, or return `undefined` if it could not be found. */
|
|
12
|
+
export function getMessage(input) {
|
|
13
|
+
return typeof input === "string" ? input : isObject(input) && typeof input.message === "string" ? input.message : undefined;
|
|
14
|
+
}
|
|
15
|
+
/** Require a message from an unknown value, or throw `RequiredError` if it could not be found. */
|
|
16
|
+
export function requireMessage(input, caller = requireMessage) {
|
|
17
|
+
const message = getMessage(input);
|
|
18
|
+
if (message === undefined)
|
|
19
|
+
throw new RequiredError("Message is required", { received: input, caller });
|
|
20
|
+
return message;
|
|
24
21
|
}
|
|
25
22
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* -
|
|
29
|
-
* -
|
|
30
|
-
* - This function extracts any `name: This is a message` lines from the full message string.
|
|
31
|
-
* - Note there may be multiple lines starting with `name:` (in the case where there were multiple errors with that name).
|
|
32
|
-
* - This trims the `name: ` prefix from found messages and rejoins them with `\n` newline.
|
|
33
|
-
*
|
|
34
|
-
* @param fullMessage The full message string which may contain named messages in `name: This is a message` format.
|
|
35
|
-
* @param name The name of the prop to extract the message for.
|
|
36
|
-
*
|
|
37
|
-
* @returns The combined message(s) for the named prop found in the full message string, or an empty string if no messages were found for that prop.
|
|
23
|
+
* Split a string message into lines, look for prefixes like `name:`, and return a dictionary of those named messages.
|
|
24
|
+
* - Full messages strings can have multiple lines separated by `\n` newline.
|
|
25
|
+
* - Named messages are extracted into their own entries in the dictionary.
|
|
26
|
+
* - Unnamed messages are combined into a single entry with the key `""` (empty string).
|
|
38
27
|
*/
|
|
39
|
-
export function
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
28
|
+
export function splitMessage(input) {
|
|
29
|
+
const messages = requireMessage(input, splitMessage).split("\n");
|
|
30
|
+
const output = {};
|
|
31
|
+
for (const line of messages) {
|
|
32
|
+
const i = line.indexOf(": ");
|
|
33
|
+
if (i >= 0) {
|
|
34
|
+
const name = line.slice(0, i).trim();
|
|
35
|
+
const message = line.slice(i + 2).trim();
|
|
36
|
+
if (Object.hasOwn(output, name))
|
|
37
|
+
output[name] += `\n${message}`;
|
|
38
|
+
else
|
|
39
|
+
output[name] = message;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const message = line.trim();
|
|
43
|
+
if (Object.hasOwn(output, ""))
|
|
44
|
+
output[""] += `\n${message}`;
|
|
45
|
+
else
|
|
46
|
+
output[""] = message;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return output;
|
|
45
50
|
}
|
package/util/index.d.ts
CHANGED
package/util/index.js
CHANGED
package/util/link.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ImmutableArray } from "./array.js";
|
|
2
2
|
import type { AnyCaller } from "./function.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Nullish } from "./null.js";
|
|
4
4
|
import type { Path } from "./path.js";
|
|
5
5
|
import { type PossibleURL } from "./url.js";
|
|
6
6
|
/**
|
|
@@ -53,7 +53,7 @@ export declare function isLinkURL(value: unknown, schemes?: LinkSchemes, hosts?:
|
|
|
53
53
|
* Convert a possible URL to a link URL, or return `undefined` if conversion fails.
|
|
54
54
|
* - A valid link URL is a `URL` instance with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
|
|
55
55
|
*/
|
|
56
|
-
export declare function getLinkURL(value:
|
|
56
|
+
export declare function getLinkURL(value: Nullish<PossibleURL>, base?: AbsoluteLinkURL | AbsoluteLink, schemes?: LinkSchemes, hosts?: LinkHosts): AbsoluteLinkURL | undefined;
|
|
57
57
|
/**
|
|
58
58
|
* Convert a possible URL to a link URL, or throw `RequiredError` if conversion fails.
|
|
59
59
|
* - A valid link URL is a `URL` instance with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
|
|
@@ -63,7 +63,7 @@ export declare function requireLinkURL(value: PossibleURL, base?: AbsoluteLinkUR
|
|
|
63
63
|
* Convert a possible URL to an link URL string, or return `undefined` if conversion fails.
|
|
64
64
|
* - A valid link URL string is an absolute URL string with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
|
|
65
65
|
*/
|
|
66
|
-
export declare function getLink(value:
|
|
66
|
+
export declare function getLink(value: Nullish<PossibleURL>, base?: AbsoluteLinkURL | AbsoluteLink, schemes?: LinkSchemes, hosts?: LinkHosts): AbsoluteLink | undefined;
|
|
67
67
|
/**
|
|
68
68
|
* Convert a possible URL to an link URL string, or throw `RequiredError` if conversion fails.
|
|
69
69
|
* - A valid link URL string is an absolute URL string with a scheme matching the `schemes` array, and `host` matching the optional `hosts` array.
|
package/util/path.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnyCaller } from "./function.js";
|
|
2
|
-
import { type
|
|
2
|
+
import { type Nullish } from "./null.js";
|
|
3
3
|
/** Absolute path string starts with `/` slash. */
|
|
4
4
|
export type AbsolutePath = `/` | `/${string}`;
|
|
5
5
|
/** Relative path string starts with `./` or `../` */
|
|
@@ -19,7 +19,7 @@ export declare function isRelativePath(path: string): path is RelativePath;
|
|
|
19
19
|
* @param base Absolute path used for resolving relative paths in `possible`
|
|
20
20
|
* @return Absolute path with a leading trailing slash, e.g. `/a/c/b`
|
|
21
21
|
*/
|
|
22
|
-
export declare function getPath(value:
|
|
22
|
+
export declare function getPath(value: Nullish<string | URL>, base?: AbsolutePath | undefined): AbsolutePath | undefined;
|
|
23
23
|
/**
|
|
24
24
|
* Resolve a relative or absolute path and return the path, or throw `RequiredError` if not a valid path.
|
|
25
25
|
* - Internally uses `new URL` to do path processing but shouldn't ever reveal that fact.
|
package/util/path.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
-
import {
|
|
2
|
+
import { notNullish } from "./null.js";
|
|
3
3
|
/** Is a string path an absolute path? */
|
|
4
4
|
export function isAbsolutePath(path) {
|
|
5
5
|
return path.startsWith("/");
|
|
@@ -23,7 +23,7 @@ function _cleanPath(path) {
|
|
|
23
23
|
* @return Absolute path with a leading trailing slash, e.g. `/a/c/b`
|
|
24
24
|
*/
|
|
25
25
|
export function getPath(value, base = "/") {
|
|
26
|
-
if (
|
|
26
|
+
if (notNullish(value)) {
|
|
27
27
|
try {
|
|
28
28
|
const { pathname, search, hash } = new URL(value, `http://j.com${base}/`);
|
|
29
29
|
if (isAbsolutePath(pathname))
|
package/util/string.d.ts
CHANGED
|
@@ -101,3 +101,7 @@ export declare function splitString(str: string, separator: string, min: 2, max?
|
|
|
101
101
|
export declare function splitString(str: string, separator: string, min: 3, max?: number, caller?: AnyCaller): readonly [string, string, string, ...string[]];
|
|
102
102
|
export declare function splitString(str: string, separator: string, min: 4, max?: number, caller?: AnyCaller): readonly [string, string, string, string, ...string[]];
|
|
103
103
|
export declare function splitString(str: string, separator: string, min?: number, max?: number, caller?: AnyCaller): ImmutableArray<string>;
|
|
104
|
+
/** Trim a string (as a function, so it can be used in mapping. */
|
|
105
|
+
export declare function trimString(str: string): string;
|
|
106
|
+
/** Does a string have length? */
|
|
107
|
+
export declare function isNonEmptyString(str: string): boolean;
|
package/util/string.js
CHANGED
|
@@ -167,3 +167,11 @@ export function splitString(str, separator, min = 1, max = Number.POSITIVE_INFIN
|
|
|
167
167
|
});
|
|
168
168
|
return segments;
|
|
169
169
|
}
|
|
170
|
+
/** Trim a string (as a function, so it can be used in mapping. */
|
|
171
|
+
export function trimString(str) {
|
|
172
|
+
return str.trim();
|
|
173
|
+
}
|
|
174
|
+
/** Does a string have length? */
|
|
175
|
+
export function isNonEmptyString(str) {
|
|
176
|
+
return str.length > 0;
|
|
177
|
+
}
|
package/util/url.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnyCaller } from "./function.js";
|
|
2
|
-
import { type
|
|
2
|
+
import { type Nullish } from "./null.js";
|
|
3
3
|
/** Values that can be converted to a URL instance. */
|
|
4
4
|
export type PossibleURL = string | URL;
|
|
5
5
|
/** Is an unknown value a URL object? */
|
|
@@ -7,6 +7,6 @@ export declare function isURL(value: unknown): value is URL;
|
|
|
7
7
|
/** Assert that an unknown value is a URL object. */
|
|
8
8
|
export declare function assertURL(value: unknown, caller?: AnyCaller): asserts value is URL;
|
|
9
9
|
/** Convert a possible URL to a URL, or return `undefined` if conversion fails. */
|
|
10
|
-
export declare function getURL(possible:
|
|
10
|
+
export declare function getURL(possible: Nullish<PossibleURL>, base?: PossibleURL | undefined): URL | undefined;
|
|
11
11
|
/** Convert a possible URL to a URL, or throw `RequiredError` if conversion fails. */
|
|
12
12
|
export declare function requireURL(possible: PossibleURL, base?: PossibleURL, caller?: AnyCaller): URL;
|
package/util/url.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
-
import {
|
|
2
|
+
import { notNullish } from "./null.js";
|
|
3
3
|
/** Is an unknown value a URL object? */
|
|
4
4
|
export function isURL(value) {
|
|
5
5
|
return value instanceof URL;
|
|
@@ -11,7 +11,7 @@ export function assertURL(value, caller = assertURL) {
|
|
|
11
11
|
}
|
|
12
12
|
/** Convert a possible URL to a URL, or return `undefined` if conversion fails. */
|
|
13
13
|
export function getURL(possible, base = _BASE) {
|
|
14
|
-
if (
|
|
14
|
+
if (notNullish(possible)) {
|
|
15
15
|
try {
|
|
16
16
|
return isURL(possible) ? possible : new URL(possible, base);
|
|
17
17
|
}
|
package/util/optional.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { AnyCaller } from "./function.js";
|
|
2
|
-
/** Optional is the value or `null` or `undefined` (synonym for `Nullish`). */
|
|
3
|
-
export type Optional<T> = T | null | undefined;
|
|
4
|
-
/** Get a required value. */
|
|
5
|
-
export declare function getRequired<T>(value: Optional<T>, caller?: AnyCaller): T;
|
|
6
|
-
/** Is a value not optional? */
|
|
7
|
-
export declare function notOptional<T>(value: Optional<T>): value is T;
|
package/util/optional.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { RequiredError } from "../error/RequiredError.js";
|
|
2
|
-
/** Get a required value. */
|
|
3
|
-
export function getRequired(value, caller = getRequired) {
|
|
4
|
-
if (value === null || value === undefined)
|
|
5
|
-
throw new RequiredError("Value is required", { received: value, caller });
|
|
6
|
-
return value;
|
|
7
|
-
}
|
|
8
|
-
/** Is a value not optional? */
|
|
9
|
-
export function notOptional(value) {
|
|
10
|
-
return value !== null && value !== undefined;
|
|
11
|
-
}
|