@serenity-js/core 2.32.7 → 3.0.0-rc.10
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/CHANGELOG.md +350 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +6 -1
- package/lib/index.js.map +1 -1
- package/lib/io/ErrorSerialiser.js +4 -1
- package/lib/io/ErrorSerialiser.js.map +1 -1
- package/lib/io/asyncMap.d.ts +8 -0
- package/lib/io/asyncMap.js +18 -0
- package/lib/io/asyncMap.js.map +1 -0
- package/lib/io/format.d.ts +39 -0
- package/lib/io/format.js +51 -0
- package/lib/io/format.js.map +1 -0
- package/lib/io/formatted.d.ts +5 -1
- package/lib/io/formatted.js +6 -13
- package/lib/io/formatted.js.map +1 -1
- package/lib/io/index.d.ts +2 -1
- package/lib/io/index.js +2 -1
- package/lib/io/index.js.map +1 -1
- package/lib/io/inspected.d.ts +9 -1
- package/lib/io/inspected.js +52 -15
- package/lib/io/inspected.js.map +1 -1
- package/lib/model/Timestamp.d.ts +4 -2
- package/lib/model/Timestamp.js +8 -2
- package/lib/model/Timestamp.js.map +1 -1
- package/lib/screenplay/Optional.d.ts +29 -0
- package/lib/{io/collections/reducible.js → screenplay/Optional.js} +1 -1
- package/lib/screenplay/Optional.js.map +1 -0
- package/lib/screenplay/Question.d.ts +41 -82
- package/lib/screenplay/Question.js +132 -100
- package/lib/screenplay/Question.js.map +1 -1
- package/lib/screenplay/actor/Actor.js +2 -2
- package/lib/screenplay/actor/Actor.js.map +1 -1
- package/lib/screenplay/index.d.ts +1 -1
- package/lib/screenplay/index.js +1 -1
- package/lib/screenplay/index.js.map +1 -1
- package/lib/screenplay/interactions/index.d.ts +0 -1
- package/lib/screenplay/interactions/index.js +0 -1
- package/lib/screenplay/interactions/index.js.map +1 -1
- package/lib/screenplay/questions/Check.d.ts +3 -3
- package/lib/screenplay/questions/Check.js +5 -7
- package/lib/screenplay/questions/Check.js.map +1 -1
- package/lib/screenplay/questions/Expectation.d.ts +15 -10
- package/lib/screenplay/questions/Expectation.js +28 -37
- package/lib/screenplay/questions/Expectation.js.map +1 -1
- package/lib/screenplay/questions/List.d.ts +22 -192
- package/lib/screenplay/questions/List.js +160 -208
- package/lib/screenplay/questions/List.js.map +1 -1
- package/lib/screenplay/questions/Note.d.ts +10 -0
- package/lib/screenplay/questions/Note.js +17 -1
- package/lib/screenplay/questions/Note.js.map +1 -1
- package/lib/screenplay/questions/index.d.ts +0 -3
- package/lib/screenplay/questions/index.js +0 -5
- package/lib/screenplay/questions/index.js.map +1 -1
- package/lib/stage/index.d.ts +0 -2
- package/lib/stage/index.js +0 -2
- package/lib/stage/index.js.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +2 -1
- package/src/io/ErrorSerialiser.ts +5 -1
- package/src/io/asyncMap.ts +18 -0
- package/src/io/format.ts +49 -0
- package/src/io/formatted.ts +7 -15
- package/src/io/index.ts +2 -1
- package/src/io/inspected.ts +68 -15
- package/src/model/Timestamp.ts +10 -2
- package/src/screenplay/Optional.ts +30 -0
- package/src/screenplay/Question.ts +206 -124
- package/src/screenplay/actor/Actor.ts +2 -2
- package/src/screenplay/index.ts +1 -1
- package/src/screenplay/interactions/index.ts +0 -1
- package/src/screenplay/questions/Check.ts +10 -15
- package/src/screenplay/questions/Expectation.ts +48 -55
- package/src/screenplay/questions/List.ts +224 -233
- package/src/screenplay/questions/Note.ts +21 -1
- package/src/screenplay/questions/index.ts +0 -3
- package/src/stage/index.ts +0 -2
- package/lib/io/collections/index.d.ts +0 -2
- package/lib/io/collections/index.js +0 -15
- package/lib/io/collections/index.js.map +0 -1
- package/lib/io/collections/mappable.d.ts +0 -52
- package/lib/io/collections/mappable.js +0 -28
- package/lib/io/collections/mappable.js.map +0 -1
- package/lib/io/collections/reducible.d.ts +0 -16
- package/lib/io/collections/reducible.js.map +0 -1
- package/lib/screenplay/interactions/See.d.ts +0 -31
- package/lib/screenplay/interactions/See.js +0 -43
- package/lib/screenplay/interactions/See.js.map +0 -1
- package/lib/screenplay/questions/Property.d.ts +0 -91
- package/lib/screenplay/questions/Property.js +0 -99
- package/lib/screenplay/questions/Property.js.map +0 -1
- package/lib/screenplay/questions/Transform.d.ts +0 -31
- package/lib/screenplay/questions/Transform.js +0 -46
- package/lib/screenplay/questions/Transform.js.map +0 -1
- package/lib/screenplay/questions/lists/ArrayListAdapter.d.ts +0 -88
- package/lib/screenplay/questions/lists/ArrayListAdapter.js +0 -152
- package/lib/screenplay/questions/lists/ArrayListAdapter.js.map +0 -1
- package/lib/screenplay/questions/lists/ListAdapter.d.ts +0 -20
- package/lib/screenplay/questions/lists/ListAdapter.js +0 -3
- package/lib/screenplay/questions/lists/ListAdapter.js.map +0 -1
- package/lib/screenplay/questions/lists/index.d.ts +0 -2
- package/lib/screenplay/questions/lists/index.js +0 -15
- package/lib/screenplay/questions/lists/index.js.map +0 -1
- package/lib/screenplay/questions/mappings/AnswerMappingFunction.d.ts +0 -11
- package/lib/screenplay/questions/mappings/AnswerMappingFunction.js +0 -3
- package/lib/screenplay/questions/mappings/AnswerMappingFunction.js.map +0 -1
- package/lib/screenplay/questions/mappings/index.d.ts +0 -2
- package/lib/screenplay/questions/mappings/index.js +0 -15
- package/lib/screenplay/questions/mappings/index.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/append.d.ts +0 -14
- package/lib/screenplay/questions/mappings/string/append.js +0 -25
- package/lib/screenplay/questions/mappings/string/append.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/index.d.ts +0 -11
- package/lib/screenplay/questions/mappings/string/index.js +0 -24
- package/lib/screenplay/questions/mappings/string/index.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/normalize.d.ts +0 -20
- package/lib/screenplay/questions/mappings/string/normalize.js +0 -30
- package/lib/screenplay/questions/mappings/string/normalize.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/replace.d.ts +0 -17
- package/lib/screenplay/questions/mappings/string/replace.js +0 -30
- package/lib/screenplay/questions/mappings/string/replace.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/slice.d.ts +0 -28
- package/lib/screenplay/questions/mappings/string/slice.js +0 -47
- package/lib/screenplay/questions/mappings/string/slice.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/split.d.ts +0 -19
- package/lib/screenplay/questions/mappings/string/split.js +0 -36
- package/lib/screenplay/questions/mappings/string/split.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toLocaleLowerCase.d.ts +0 -17
- package/lib/screenplay/questions/mappings/string/toLocaleLowerCase.js +0 -28
- package/lib/screenplay/questions/mappings/string/toLocaleLowerCase.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toLocaleUpperCase.d.ts +0 -17
- package/lib/screenplay/questions/mappings/string/toLocaleUpperCase.js +0 -29
- package/lib/screenplay/questions/mappings/string/toLocaleUpperCase.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toLowerCase.d.ts +0 -10
- package/lib/screenplay/questions/mappings/string/toLowerCase.js +0 -19
- package/lib/screenplay/questions/mappings/string/toLowerCase.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toNumber.d.ts +0 -10
- package/lib/screenplay/questions/mappings/string/toNumber.js +0 -18
- package/lib/screenplay/questions/mappings/string/toNumber.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/toUpperCase.d.ts +0 -10
- package/lib/screenplay/questions/mappings/string/toUpperCase.js +0 -19
- package/lib/screenplay/questions/mappings/string/toUpperCase.js.map +0 -1
- package/lib/screenplay/questions/mappings/string/trim.d.ts +0 -12
- package/lib/screenplay/questions/mappings/string/trim.js +0 -21
- package/lib/screenplay/questions/mappings/string/trim.js.map +0 -1
- package/lib/screenplay/questions/proxies/PropertyPathKey.d.ts +0 -4
- package/lib/screenplay/questions/proxies/PropertyPathKey.js +0 -3
- package/lib/screenplay/questions/proxies/PropertyPathKey.js.map +0 -1
- package/lib/screenplay/questions/proxies/createMetaQuestionProxy.d.ts +0 -14
- package/lib/screenplay/questions/proxies/createMetaQuestionProxy.js +0 -35
- package/lib/screenplay/questions/proxies/createMetaQuestionProxy.js.map +0 -1
- package/lib/screenplay/questions/proxies/createQuestionProxy.d.ts +0 -13
- package/lib/screenplay/questions/proxies/createQuestionProxy.js +0 -34
- package/lib/screenplay/questions/proxies/createQuestionProxy.js.map +0 -1
- package/lib/screenplay/questions/proxies/describePath.d.ts +0 -5
- package/lib/screenplay/questions/proxies/describePath.js +0 -19
- package/lib/screenplay/questions/proxies/describePath.js.map +0 -1
- package/lib/screenplay/questions/proxies/index.d.ts +0 -2
- package/lib/screenplay/questions/proxies/index.js +0 -15
- package/lib/screenplay/questions/proxies/index.js.map +0 -1
- package/lib/screenplay/questions/proxies/key.d.ts +0 -8
- package/lib/screenplay/questions/proxies/key.js +0 -16
- package/lib/screenplay/questions/proxies/key.js.map +0 -1
- package/lib/screenplay/tasks/Loop.d.ts +0 -198
- package/lib/screenplay/tasks/Loop.js +0 -222
- package/lib/screenplay/tasks/Loop.js.map +0 -1
- package/lib/screenplay/tasks/index.d.ts +0 -1
- package/lib/screenplay/tasks/index.js +0 -14
- package/lib/screenplay/tasks/index.js.map +0 -1
- package/lib/stage/DressingRoom.d.ts +0 -37
- package/lib/stage/DressingRoom.js +0 -53
- package/lib/stage/DressingRoom.js.map +0 -1
- package/lib/stage/WithStage.d.ts +0 -51
- package/lib/stage/WithStage.js +0 -3
- package/lib/stage/WithStage.js.map +0 -1
- package/src/io/collections/index.ts +0 -2
- package/src/io/collections/mappable.ts +0 -60
- package/src/io/collections/reducible.ts +0 -16
- package/src/screenplay/interactions/See.ts +0 -45
- package/src/screenplay/questions/Property.ts +0 -98
- package/src/screenplay/questions/Transform.ts +0 -51
- package/src/screenplay/questions/lists/ArrayListAdapter.ts +0 -186
- package/src/screenplay/questions/lists/ListAdapter.ts +0 -33
- package/src/screenplay/questions/lists/index.ts +0 -2
- package/src/screenplay/questions/mappings/AnswerMappingFunction.ts +0 -13
- package/src/screenplay/questions/mappings/index.ts +0 -2
- package/src/screenplay/questions/mappings/string/append.ts +0 -28
- package/src/screenplay/questions/mappings/string/index.ts +0 -11
- package/src/screenplay/questions/mappings/string/normalize.ts +0 -33
- package/src/screenplay/questions/mappings/string/replace.ts +0 -34
- package/src/screenplay/questions/mappings/string/slice.ts +0 -53
- package/src/screenplay/questions/mappings/string/split.ts +0 -38
- package/src/screenplay/questions/mappings/string/toLocaleLowerCase.ts +0 -31
- package/src/screenplay/questions/mappings/string/toLocaleUpperCase.ts +0 -30
- package/src/screenplay/questions/mappings/string/toLowerCase.ts +0 -20
- package/src/screenplay/questions/mappings/string/toNumber.ts +0 -19
- package/src/screenplay/questions/mappings/string/toUpperCase.ts +0 -20
- package/src/screenplay/questions/mappings/string/trim.ts +0 -22
- package/src/screenplay/questions/proxies/PropertyPathKey.ts +0 -4
- package/src/screenplay/questions/proxies/createMetaQuestionProxy.ts +0 -51
- package/src/screenplay/questions/proxies/createQuestionProxy.ts +0 -49
- package/src/screenplay/questions/proxies/describePath.ts +0 -23
- package/src/screenplay/questions/proxies/index.ts +0 -2
- package/src/screenplay/questions/proxies/key.ts +0 -14
- package/src/screenplay/tasks/Loop.ts +0 -240
- package/src/screenplay/tasks/index.ts +0 -1
- package/src/stage/DressingRoom.ts +0 -53
- package/src/stage/WithStage.ts +0 -52
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { ensure, isArray, isNumber } from 'tiny-types';
|
|
2
|
-
|
|
3
|
-
import { formatted } from '../../../io';
|
|
4
|
-
import { AnswersQuestions, UsesAbilities } from '../../actor';
|
|
5
|
-
import { Answerable } from '../../Answerable';
|
|
6
|
-
import { Question } from '../../Question';
|
|
7
|
-
import { Expectation } from '../Expectation';
|
|
8
|
-
import { ExpectationMet } from '../expectations';
|
|
9
|
-
import { MetaQuestion } from '../MetaQuestion';
|
|
10
|
-
import { ListAdapter } from './ListAdapter';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @desc
|
|
14
|
-
* Adapts an {@link Array} so that it can be used with {@link List}
|
|
15
|
-
*
|
|
16
|
-
* @implements {ListAdapter}
|
|
17
|
-
*/
|
|
18
|
-
export class ArrayListAdapter<Item_Type> implements ListAdapter<Item_Type, Item_Type[], Promise<Item_Type>, Promise<Item_Type[]>> {
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @param {Answerable<Item_Type[]>} array
|
|
22
|
-
*/
|
|
23
|
-
constructor(private readonly array: Answerable<Item_Type[]>) {
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @desc
|
|
28
|
-
* Returns the number of items the underlying {@link Array} contains,
|
|
29
|
-
* left after applying any filters.
|
|
30
|
-
*
|
|
31
|
-
* @param {AnswersQuestions & UsesAbilities} actor
|
|
32
|
-
* @returns {Promise<number>}
|
|
33
|
-
*/
|
|
34
|
-
count(actor: AnswersQuestions & UsesAbilities): Promise<number> {
|
|
35
|
-
return this.arrayAs(actor)
|
|
36
|
-
.then(items => items.length);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @desc
|
|
41
|
-
* Returns the underlying {@link Array},
|
|
42
|
-
* with any filters applied.
|
|
43
|
-
*
|
|
44
|
-
* @param {AnswersQuestions & UsesAbilities} actor
|
|
45
|
-
* @returns {Promise<number>}
|
|
46
|
-
*/
|
|
47
|
-
items(actor: AnswersQuestions & UsesAbilities): Promise<Item_Type[]> {
|
|
48
|
-
return this.arrayAs(actor);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @desc
|
|
53
|
-
* Returns the first of items the underlying {@link Array} contains,
|
|
54
|
-
* left after applying any filters.
|
|
55
|
-
*
|
|
56
|
-
* @param {AnswersQuestions & UsesAbilities} actor
|
|
57
|
-
* @returns {Promise<Item_Type>}
|
|
58
|
-
*/
|
|
59
|
-
first(actor: AnswersQuestions & UsesAbilities): Promise<Item_Type> {
|
|
60
|
-
return this.arrayAs(actor)
|
|
61
|
-
.then(items => this.getItemAt(items, 0));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @desc
|
|
66
|
-
* Returns the nth of items the underlying {@link Array} contains,
|
|
67
|
-
* left after applying any filters.
|
|
68
|
-
*
|
|
69
|
-
* @param {AnswersQuestions & UsesAbilities} actor
|
|
70
|
-
*
|
|
71
|
-
* @param {number} index
|
|
72
|
-
* Zero-based index of the item to return
|
|
73
|
-
*
|
|
74
|
-
* @returns {Promise<Item_Type>}
|
|
75
|
-
*/
|
|
76
|
-
get(actor: AnswersQuestions & UsesAbilities, index: number): Promise<Item_Type> {
|
|
77
|
-
return this.arrayAs(actor)
|
|
78
|
-
.then(items => this.getItemAt(items, index));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @desc
|
|
83
|
-
* Returns the last of items the underlying {@link Array} contains,
|
|
84
|
-
* left after applying any filters.
|
|
85
|
-
*
|
|
86
|
-
* @param {AnswersQuestions & UsesAbilities} actor
|
|
87
|
-
* @returns {Promise<Item_Type>}
|
|
88
|
-
*/
|
|
89
|
-
last(actor: AnswersQuestions & UsesAbilities): Promise<Item_Type> {
|
|
90
|
-
return this.arrayAs(actor)
|
|
91
|
-
.then(items => this.getItemAt(items, items.length - 1));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* @desc
|
|
96
|
-
* Filters the underlying {@link Array} so that the result contains only those items that meet the {@link Expectation}
|
|
97
|
-
*
|
|
98
|
-
* @param {MetaQuestion<Item_Type, Promise<Answer_Type> | Answer_Type>} question
|
|
99
|
-
* @param {Expectation<any, Answer_Type>} expectation
|
|
100
|
-
*
|
|
101
|
-
* @returns {ListAdapter<Item_Type, Item_Type[], Promise<Item_Type>, Promise<Item_Type[]>>}
|
|
102
|
-
*
|
|
103
|
-
* @see {MetaQuestion}
|
|
104
|
-
*/
|
|
105
|
-
withFilter<Answer_Type>(
|
|
106
|
-
question: MetaQuestion<Item_Type, Promise<Answer_Type> | Answer_Type>,
|
|
107
|
-
expectation: Expectation<any, Answer_Type>
|
|
108
|
-
): ListAdapter<Item_Type, Item_Type[], Promise<Item_Type>, Promise<Item_Type[]>> {
|
|
109
|
-
return new ArrayListAdapter(
|
|
110
|
-
new ArrayListFilter(this.array, question, expectation)
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* @desc
|
|
116
|
-
* Returns a human-readable description of the underlying {@link Array}.
|
|
117
|
-
*
|
|
118
|
-
* @returns {string}
|
|
119
|
-
*/
|
|
120
|
-
toString(): string {
|
|
121
|
-
return formatted `${ this.array }`
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private arrayAs(actor: AnswersQuestions & UsesAbilities): Promise<Item_Type[]> {
|
|
125
|
-
return actor.answer(this.array)
|
|
126
|
-
.then(array => ensure('ArrayListAdapter constructor parameter', array, isArray()));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
private getItemAt(items: Item_Type[], index: number): Item_Type {
|
|
130
|
-
|
|
131
|
-
ensure('index', index, isNumber());
|
|
132
|
-
|
|
133
|
-
const collectionDescription = this.toString();
|
|
134
|
-
const itemsDescription = formatted`${ items }`;
|
|
135
|
-
const description = collectionDescription !== itemsDescription
|
|
136
|
-
? `${ collectionDescription } ${ itemsDescription }`
|
|
137
|
-
: itemsDescription;
|
|
138
|
-
|
|
139
|
-
if (items.length === 0) {
|
|
140
|
-
throw new Error(`${ description } is empty`);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (index in items) {
|
|
144
|
-
return items[index];
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
throw new Error(`${ description } has no item at index ${ index }`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* @package
|
|
153
|
-
*/
|
|
154
|
-
class ArrayListFilter<Item_Type, Answer_Type>
|
|
155
|
-
extends Question<Promise<Item_Type[]>>
|
|
156
|
-
{
|
|
157
|
-
constructor(
|
|
158
|
-
private readonly collection: Answerable<Item_Type[]>,
|
|
159
|
-
private readonly question: MetaQuestion<Item_Type, Promise<Answer_Type> | Answer_Type>,
|
|
160
|
-
private readonly expectation: Expectation<any, Answer_Type>
|
|
161
|
-
) {
|
|
162
|
-
super([
|
|
163
|
-
formatted `${ collection }`,
|
|
164
|
-
collection instanceof ArrayListFilter ? 'and' : 'where',
|
|
165
|
-
formatted `${ question } does ${ expectation }`
|
|
166
|
-
].join(' '));
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
answeredBy(actor: AnswersQuestions & UsesAbilities): Promise<Item_Type[]> {
|
|
170
|
-
|
|
171
|
-
return actor.answer(this.collection)
|
|
172
|
-
.then(array => ensure('ArrayListAdapter constructor parameter', array, isArray())) // todo: extract to avoid duplication?
|
|
173
|
-
.then(array =>
|
|
174
|
-
Promise.all(array.map(item =>
|
|
175
|
-
Promise.resolve(this.question.of(item).answeredBy(actor))
|
|
176
|
-
.then(answer => this.expectation.answeredBy(actor)(answer))
|
|
177
|
-
.then(outcome => ({ item, outcome }))
|
|
178
|
-
))
|
|
179
|
-
)
|
|
180
|
-
.then(results =>
|
|
181
|
-
results.filter(result => result.outcome instanceof ExpectationMet)
|
|
182
|
-
.map(result => result.item)
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { AnswersQuestions, UsesAbilities } from '../../actor';
|
|
2
|
-
import { Expectation } from '../Expectation';
|
|
3
|
-
import { MetaQuestion } from '../MetaQuestion';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @desc
|
|
7
|
-
* Adapts various types of collections so that they can be used with {@link List}.
|
|
8
|
-
*
|
|
9
|
-
* You probably won't need to implement this interface, unless you're extending Serenity/JS.
|
|
10
|
-
*
|
|
11
|
-
* @see {@link List}
|
|
12
|
-
*/
|
|
13
|
-
export interface ListAdapter<
|
|
14
|
-
Item_Type,
|
|
15
|
-
Collection_Type,
|
|
16
|
-
Item_Return_Type = Item_Type,
|
|
17
|
-
Collection_Return_Type = Collection_Type
|
|
18
|
-
> {
|
|
19
|
-
count(actor: AnswersQuestions & UsesAbilities): Promise<number>;
|
|
20
|
-
|
|
21
|
-
first(actor: AnswersQuestions & UsesAbilities): Item_Return_Type;
|
|
22
|
-
last(actor: AnswersQuestions & UsesAbilities): Item_Return_Type;
|
|
23
|
-
get(actor: AnswersQuestions & UsesAbilities, index: number): Item_Return_Type;
|
|
24
|
-
|
|
25
|
-
items(actor: AnswersQuestions & UsesAbilities): Collection_Return_Type;
|
|
26
|
-
|
|
27
|
-
withFilter<Answer_Type>(
|
|
28
|
-
question: MetaQuestion<Item_Type, Promise<Answer_Type> | Answer_Type>,
|
|
29
|
-
expectation: Expectation<any, Answer_Type>,
|
|
30
|
-
): ListAdapter<Item_Type, Collection_Type, Item_Return_Type, Collection_Return_Type>;
|
|
31
|
-
|
|
32
|
-
toString(): string;
|
|
33
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { MappingFunction } from '../../../io/collections';
|
|
2
|
-
import { AnswersQuestions } from '../../actor';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @desc
|
|
6
|
-
* A mapping function converting one type into another.
|
|
7
|
-
*
|
|
8
|
-
* @public
|
|
9
|
-
*
|
|
10
|
-
* @typedef {function(actor: AnswersQuestions) => MappingFunction<V,O>} AnswerMappingFunction<V, O>
|
|
11
|
-
*/
|
|
12
|
-
export type AnswerMappingFunction<V, O> =
|
|
13
|
-
(actor: AnswersQuestions) => MappingFunction<V, Promise<O> | O>
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { Answerable } from '../../../Answerable';
|
|
6
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @desc
|
|
10
|
-
* Appends the values to the end of the original string and returns a new string.
|
|
11
|
-
*
|
|
12
|
-
* @param {...Array<Answerable<string>>} values
|
|
13
|
-
* The values to append to the end of the string.
|
|
14
|
-
*
|
|
15
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
16
|
-
*
|
|
17
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat
|
|
18
|
-
*/
|
|
19
|
-
export function append(...values: Array<Answerable<string>>): AnswerMappingFunction<string, string> {
|
|
20
|
-
return (actor: AnswersQuestions) =>
|
|
21
|
-
(originalAnswer: string) => {
|
|
22
|
-
|
|
23
|
-
ensure('The value to be mapped', originalAnswer, isDefined(), isString());
|
|
24
|
-
|
|
25
|
-
return Promise.all(values.map(value => actor.answer(value)))
|
|
26
|
-
.then(answers => originalAnswer.concat(...answers))
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export * from './append';
|
|
2
|
-
export * from './normalize';
|
|
3
|
-
export * from './replace';
|
|
4
|
-
export * from './slice';
|
|
5
|
-
export * from './split';
|
|
6
|
-
export * from './toLocaleLowerCase';
|
|
7
|
-
export * from './toLocaleUpperCase';
|
|
8
|
-
export * from './toLowerCase';
|
|
9
|
-
export * from './toNumber';
|
|
10
|
-
export * from './toUpperCase';
|
|
11
|
-
export * from './trim';
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { Answerable } from '../../../Answerable';
|
|
6
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @desc
|
|
10
|
-
* Returns the String value result of normalizing the string into the normalization form
|
|
11
|
-
* named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms.
|
|
12
|
-
*
|
|
13
|
-
* @param {Answerable<string>} [form]
|
|
14
|
-
* One of "NFC", "NFD", "NFKC", or "NFKD", specifying the Unicode Normalization Form. If omitted or undefined, "NFC" is used.
|
|
15
|
-
* These values have the following meanings:
|
|
16
|
-
* "NFC" - Canonical Decomposition, followed by Canonical Composition.
|
|
17
|
-
* "NFD" - Canonical Decomposition.
|
|
18
|
-
* "NFKC" - Compatibility Decomposition, followed by Canonical Composition.
|
|
19
|
-
* "NFKD" - Compatibility Decomposition.
|
|
20
|
-
*
|
|
21
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
22
|
-
*
|
|
23
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
|
|
24
|
-
*/
|
|
25
|
-
export function normalize(form?: Answerable<string>): AnswerMappingFunction<string, string> {
|
|
26
|
-
return (actor: AnswersQuestions) =>
|
|
27
|
-
(value: string) => {
|
|
28
|
-
|
|
29
|
-
ensure('The value to be mapped', value, isDefined(), isString())
|
|
30
|
-
|
|
31
|
-
return actor.answer(form).then(answer => value.normalize(answer));
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { Answerable } from '../../../Answerable';
|
|
6
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @desc
|
|
10
|
-
* Returns a new string with some or all matches of a pattern replaced by a replacement.
|
|
11
|
-
* The pattern can be a string or a RegExp, and the replacement can be a string or a function to be called for each match.
|
|
12
|
-
* If pattern is a string, only the first occurrence will be replaced.
|
|
13
|
-
*
|
|
14
|
-
* @param {Answerable<string | RegExp>} pattern
|
|
15
|
-
*
|
|
16
|
-
* @param {Answerable<string|function>} replacement
|
|
17
|
-
*
|
|
18
|
-
* @returns {MappingFunction<string, string>}
|
|
19
|
-
*
|
|
20
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
|
|
21
|
-
*/
|
|
22
|
-
export function replace(pattern: Answerable<RegExp | string>, replacement: Answerable<string | ((substring: string, ...args: any[]) => string)>): AnswerMappingFunction<string, string> {
|
|
23
|
-
return (actor: AnswersQuestions) =>
|
|
24
|
-
(value: string) => {
|
|
25
|
-
ensure('The value to be mapped', value, isDefined(), isString())
|
|
26
|
-
|
|
27
|
-
return Promise.all([
|
|
28
|
-
actor.answer(pattern),
|
|
29
|
-
actor.answer(replacement),
|
|
30
|
-
]).then(([p, r]) =>
|
|
31
|
-
value.replace(p, r as any),
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isInteger, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { Answerable } from '../../../Answerable';
|
|
6
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @desc
|
|
10
|
-
* Extracts the part of the string between the `startIndex` and `endIndex` indexes, or to the end of the string if `endIndex` is `undefined`.
|
|
11
|
-
*
|
|
12
|
-
* @param {Answerable<number>} startIndex
|
|
13
|
-
* The zero-based index at which to begin extraction.
|
|
14
|
-
*
|
|
15
|
-
* If negative, it is treated as `str.length + startIndex`. For example, if `startIndex` is `-3`, it is treated as `str.length - 3`
|
|
16
|
-
*
|
|
17
|
-
* If `startIndex` is greater than or equal to `str.length`, an empty string is returned.
|
|
18
|
-
*
|
|
19
|
-
* @param {Answerable<number>} [endIndex]
|
|
20
|
-
* The zero-based index _before_ which to endIndex extraction.
|
|
21
|
-
* The character at this index will not be included.
|
|
22
|
-
*
|
|
23
|
-
* If `endIndex` is omitted or undefined, or greater than `str.length`,
|
|
24
|
-
* `slice()` extracts to the endIndex of the string.
|
|
25
|
-
*
|
|
26
|
-
* If negative, it is treated as `str.length + endIndex`.
|
|
27
|
-
* For example, if `endIndex` is `-3`, it is treated as `str.length - 3`.
|
|
28
|
-
*
|
|
29
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
30
|
-
*
|
|
31
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring
|
|
32
|
-
*/
|
|
33
|
-
export function slice(startIndex: Answerable<number>, endIndex?: Answerable<number>): AnswerMappingFunction<string, string> {
|
|
34
|
-
return (actor: AnswersQuestions) =>
|
|
35
|
-
(value: string) => {
|
|
36
|
-
|
|
37
|
-
ensure('The value to be mapped', value, isDefined(), isString())
|
|
38
|
-
|
|
39
|
-
return Promise.all([
|
|
40
|
-
actor.answer(startIndex),
|
|
41
|
-
actor.answer(endIndex),
|
|
42
|
-
]).then(([ start, end ]) => {
|
|
43
|
-
|
|
44
|
-
ensure('startIndex', start, isDefined(), isInteger())
|
|
45
|
-
|
|
46
|
-
if (end !== undefined) {
|
|
47
|
-
ensure('endIndex', end, isInteger());
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return value.slice(start, end);
|
|
51
|
-
});
|
|
52
|
-
};
|
|
53
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isNotBlank, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @desc
|
|
9
|
-
* Divides a string into an ordered list of substrings, puts these substrings into an array, and returns the array.
|
|
10
|
-
* The division is done by searching for a pattern; where the pattern is provided as the first parameter in the method's call.
|
|
11
|
-
*
|
|
12
|
-
* @param {Answerable<string | RegExp>} separator
|
|
13
|
-
* The pattern describing where each split should occur. The separator can be a simple string or it can be a regular expression.
|
|
14
|
-
*
|
|
15
|
-
* @param {Answerable<number>} [limit]
|
|
16
|
-
* A non-negative integer specifying a limit on the number of substrings to be included in the array.
|
|
17
|
-
* If provided, splits the string at each occurrence of the specified separator, but stops when limit entries have been placed in the array.
|
|
18
|
-
* Any leftover text is not included in the array at all.
|
|
19
|
-
*
|
|
20
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
21
|
-
*
|
|
22
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
|
|
23
|
-
*/
|
|
24
|
-
export function split(separator: string | RegExp, limit?: number): AnswerMappingFunction<string, string[]> {
|
|
25
|
-
return (actor: AnswersQuestions) =>
|
|
26
|
-
(value: string) => {
|
|
27
|
-
ensure('The value to be mapped', value, isDefined(), isString())
|
|
28
|
-
|
|
29
|
-
return Promise.all([
|
|
30
|
-
actor.answer(separator),
|
|
31
|
-
actor.answer(limit),
|
|
32
|
-
]).then(([ s, l ]) => {
|
|
33
|
-
ensure('The separator', value, isDefined(), isString(), isNotBlank());
|
|
34
|
-
|
|
35
|
-
return value.split(s, l);
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { Answerable } from '../../../Answerable';
|
|
6
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @desc
|
|
10
|
-
* Returns the calling string value converted to upper case, according to any locale-specific case mappings.
|
|
11
|
-
*
|
|
12
|
-
* @param {Answerable<string | string[]>} [locales]
|
|
13
|
-
* The `locale` parameter indicates the locale to be used to convert to lower case according to any
|
|
14
|
-
* locale-specific case mappings. If multiple locales are given in an `Array`,
|
|
15
|
-
* the [best available locale](https://tc39.es/ecma402/#sec-bestavailablelocale) is used.
|
|
16
|
-
* The default locale is the host environment’s current locale.
|
|
17
|
-
*
|
|
18
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
19
|
-
*
|
|
20
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase
|
|
21
|
-
*/
|
|
22
|
-
export function toLocaleLowerCase(locales?: Answerable<string | string[]>): AnswerMappingFunction<string, string> {
|
|
23
|
-
return (actor: AnswersQuestions) =>
|
|
24
|
-
(value: string) => {
|
|
25
|
-
ensure('The value to be mapped', value, isDefined(), isString());
|
|
26
|
-
|
|
27
|
-
return actor.answer(locales)
|
|
28
|
-
.then(l => value.toLocaleLowerCase(l));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @desc
|
|
9
|
-
* Returns a string where all alphabetic characters have been converted to uppercase,
|
|
10
|
-
* taking into account the host environment's current locale.
|
|
11
|
-
*
|
|
12
|
-
* @param {Answerable<string | string[]>} [locales]
|
|
13
|
-
* The `locale` parameter indicates the locale to be used to convert to lower case according to any
|
|
14
|
-
* locale-specific case mappings. If multiple locales are given in an `Array`,
|
|
15
|
-
* the [best available locale](https://tc39.es/ecma402/#sec-bestavailablelocale) is used.
|
|
16
|
-
* The default locale is the host environment’s current locale.
|
|
17
|
-
*
|
|
18
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
19
|
-
*
|
|
20
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase
|
|
21
|
-
*/
|
|
22
|
-
export function toLocaleUpperCase(locales?: string | string[]): AnswerMappingFunction<string, string> {
|
|
23
|
-
return (actor: AnswersQuestions) =>
|
|
24
|
-
(value: string) => {
|
|
25
|
-
ensure('The value to be mapped', value, isDefined(), isString());
|
|
26
|
-
|
|
27
|
-
return actor.answer(locales)
|
|
28
|
-
.then(l => value.toLocaleUpperCase(l));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @desc
|
|
9
|
-
* Converts all the alphabetic characters in a string to lowercase.
|
|
10
|
-
*
|
|
11
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
12
|
-
*
|
|
13
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase
|
|
14
|
-
*/
|
|
15
|
-
export function toLowerCase(): AnswerMappingFunction<string, string> {
|
|
16
|
-
return (actor: AnswersQuestions) =>
|
|
17
|
-
(value: string) =>
|
|
18
|
-
ensure('The value to be mapped', value, isDefined(), isString())
|
|
19
|
-
.toLowerCase();
|
|
20
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @desc
|
|
9
|
-
* Converts a `string` to a `number`.
|
|
10
|
-
*
|
|
11
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
12
|
-
*
|
|
13
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
|
|
14
|
-
*/
|
|
15
|
-
export function toNumber(): AnswerMappingFunction<string, number> {
|
|
16
|
-
return (actor: AnswersQuestions) =>
|
|
17
|
-
(value: string) =>
|
|
18
|
-
Number(ensure('value', value, isDefined()));
|
|
19
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @desc
|
|
9
|
-
* Converts all the alphabetic characters in a string to uppercase.
|
|
10
|
-
*
|
|
11
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
12
|
-
*
|
|
13
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase
|
|
14
|
-
*/
|
|
15
|
-
export function toUpperCase(): AnswerMappingFunction<string, string> {
|
|
16
|
-
return (actor: AnswersQuestions) =>
|
|
17
|
-
(value: string) =>
|
|
18
|
-
ensure('The value to be mapped', value, isDefined(), isString())
|
|
19
|
-
.toUpperCase();
|
|
20
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/* eslint-disable unicorn/consistent-function-scoping */
|
|
2
|
-
import { ensure, isDefined, isString } from 'tiny-types';
|
|
3
|
-
|
|
4
|
-
import { AnswersQuestions } from '../../../actor';
|
|
5
|
-
import { AnswerMappingFunction } from '../AnswerMappingFunction';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @desc
|
|
9
|
-
* Removes whitespace from both ends of a string.
|
|
10
|
-
* Whitespace in this context is all the whitespace characters (space, tab, no-break space, etc.)
|
|
11
|
-
* and all the line terminator characters (LF, CR, etc.).
|
|
12
|
-
*
|
|
13
|
-
* @returns {AnswerMappingFunction<string, string>}
|
|
14
|
-
*
|
|
15
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim
|
|
16
|
-
*/
|
|
17
|
-
export function trim(): AnswerMappingFunction<string, string> {
|
|
18
|
-
return (actor: AnswersQuestions) =>
|
|
19
|
-
(value: string) =>
|
|
20
|
-
ensure('The value to be mapped', value, isDefined(), isString())
|
|
21
|
-
.trim();
|
|
22
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
-
import { formatted } from '../../../io';
|
|
3
|
-
import { Answerable } from '../../Answerable';
|
|
4
|
-
import { Question } from '../../Question';
|
|
5
|
-
import { MetaQuestion } from '../MetaQuestion';
|
|
6
|
-
import { describePath } from './describePath';
|
|
7
|
-
import { key } from './key';
|
|
8
|
-
import { PropertyPathKey } from './PropertyPathKey';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @package
|
|
12
|
-
*/
|
|
13
|
-
export type WithPropertiesAsMetaQuestions<Original_Type, Nested_Type = Original_Type> = {
|
|
14
|
-
[Key in keyof Nested_Type]: Nested_Type[Key] extends object
|
|
15
|
-
? Question<Promise<Nested_Type[Key]>> & MetaQuestion<Answerable<Original_Type>, Promise<Nested_Type[Key]>> & WithPropertiesAsMetaQuestions<Original_Type, Nested_Type[Key]>
|
|
16
|
-
: Question<Promise<Nested_Type[Key]>> & MetaQuestion<Answerable<Original_Type>, Promise<Nested_Type[Key]>>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @package
|
|
21
|
-
*/
|
|
22
|
-
export function createMetaQuestionProxy<Original_Type extends object>(path: PropertyPathKey[] = []): WithPropertiesAsMetaQuestions<Original_Type> {
|
|
23
|
-
|
|
24
|
-
const empty = {};
|
|
25
|
-
|
|
26
|
-
return new Proxy<Original_Type>(empty as any, {
|
|
27
|
-
get(target: unknown, name: PropertyPathKey) {
|
|
28
|
-
|
|
29
|
-
if (key(name).isOneOf<MetaQuestion<Answerable<Original_Type>, Promise<any>>>('of')) {
|
|
30
|
-
|
|
31
|
-
return function of(subject: Answerable<Original_Type>) {
|
|
32
|
-
|
|
33
|
-
return Question.about(formatted `property ${ describePath(path) } of ${ subject }`, actor => {
|
|
34
|
-
return actor.answer(subject).then(answer => {
|
|
35
|
-
|
|
36
|
-
return path.reduce((subObject, keyName, index) => {
|
|
37
|
-
if (keyName in subObject) {
|
|
38
|
-
return subObject[keyName];
|
|
39
|
-
}
|
|
40
|
-
throw new Error(formatted `property ${ describePath(path.slice(0, index + 1)) } of ${ subject } doesn't exist`);
|
|
41
|
-
}, answer);
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return createMetaQuestionProxy<Original_Type>(path.concat(name));
|
|
49
|
-
}
|
|
50
|
-
}) as WithPropertiesAsMetaQuestions<Original_Type>;
|
|
51
|
-
}
|