@modular-component/core 0.1.3 → 0.1.5
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 +13 -0
- package/dist/index.d.ts +304 -91
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +107 -53
- package/dist/index.js.map +1 -1
- package/dist/types/arguments.d.ts +33 -0
- package/dist/types/arguments.d.ts.map +1 -0
- package/dist/types/arguments.js +6 -0
- package/dist/types/arguments.js.map +1 -0
- package/dist/types/methods/add.d.ts +23 -0
- package/dist/types/methods/add.d.ts.map +1 -0
- package/dist/types/methods/add.js +8 -0
- package/dist/types/methods/add.js.map +1 -0
- package/dist/types/methods/at.d.ts +22 -0
- package/dist/types/methods/at.d.ts.map +1 -0
- package/dist/types/methods/at.js +7 -0
- package/dist/types/methods/at.js.map +1 -0
- package/dist/types/methods/hook.d.ts +14 -0
- package/dist/types/methods/hook.d.ts.map +1 -0
- package/dist/types/methods/hook.js +7 -0
- package/dist/types/methods/hook.js.map +1 -0
- package/dist/types/methods/mock.d.ts +26 -0
- package/dist/types/methods/mock.d.ts.map +1 -0
- package/dist/types/methods/mock.js +6 -0
- package/dist/types/methods/mock.js.map +1 -0
- package/dist/types/methods/with.d.ts +44 -0
- package/dist/types/methods/with.d.ts.map +1 -0
- package/dist/types/methods/with.js +8 -0
- package/dist/types/methods/with.js.map +1 -0
- package/dist/types/methods.d.ts +10 -0
- package/dist/types/methods.d.ts.map +1 -0
- package/dist/types/methods.js +5 -0
- package/dist/types/methods.js.map +1 -0
- package/dist/types/modular-component.d.ts +15 -0
- package/dist/types/modular-component.d.ts.map +1 -0
- package/dist/types/modular-component.js +5 -0
- package/dist/types/modular-component.js.map +1 -0
- package/dist/types/stage.d.ts +41 -0
- package/dist/types/stage.d.ts.map +1 -0
- package/dist/types/stage.js +5 -0
- package/dist/types/stage.js.map +1 -0
- package/dist/types/utils.d.ts +24 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +5 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/types/validation.d.ts +4 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +2 -0
- package/dist/types/validation.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +185 -83
- package/src/types/arguments.ts +55 -0
- package/src/types/methods/add.ts +50 -0
- package/src/types/methods/at.ts +64 -0
- package/src/types/methods/hook.ts +27 -0
- package/src/types/methods/mock.ts +90 -0
- package/src/types/methods/with.ts +153 -0
- package/src/types/methods.ts +11 -0
- package/src/types/modular-component.ts +25 -0
- package/src/types/stage.ts +91 -0
- package/src/types/utils.ts +63 -0
- package/src/types/validation.ts +13 -0
- package/dist/types.d.ts +0 -79
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/src/types.ts +0 -279
package/src/types.ts
DELETED
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import { FunctionComponent } from 'react'
|
|
2
|
-
|
|
3
|
-
// Collapse a union of similar object into the intersection of the various objects
|
|
4
|
-
type UnionToIntersection<U> = [U] extends [never]
|
|
5
|
-
? never
|
|
6
|
-
: (U extends infer V ? (k: U) => void : never) extends (k: infer I) => void
|
|
7
|
-
? I
|
|
8
|
-
: never
|
|
9
|
-
|
|
10
|
-
// Base types used for manipulating stages
|
|
11
|
-
export type StageEntry = { key: MethodName; value: unknown; stages: string }
|
|
12
|
-
type StageList = StageEntry[]
|
|
13
|
-
|
|
14
|
-
// Base type used for manipulating methods
|
|
15
|
-
export type MethodName = `with${Capitalize<string>}`
|
|
16
|
-
export type MethodEntry = {
|
|
17
|
-
field: string
|
|
18
|
-
transform?: (args: any, value: any) => any
|
|
19
|
-
restrict?: unknown
|
|
20
|
-
multiple?: boolean
|
|
21
|
-
empty?: boolean
|
|
22
|
-
symbol?: symbol
|
|
23
|
-
}
|
|
24
|
-
export type MethodRecord = Record<MethodName, MethodEntry>
|
|
25
|
-
|
|
26
|
-
// Take a stage list, and append a new stage at the end
|
|
27
|
-
type AppendStage<
|
|
28
|
-
List extends StageList,
|
|
29
|
-
Stage extends MethodName,
|
|
30
|
-
Value extends unknown,
|
|
31
|
-
Prev extends StageEntry = GetStage<List, Stage>,
|
|
32
|
-
> = [
|
|
33
|
-
...List,
|
|
34
|
-
{
|
|
35
|
-
key: Stage
|
|
36
|
-
value: Value
|
|
37
|
-
stages: [Prev] extends [never] ? List[number]['key'] : Prev['stages']
|
|
38
|
-
},
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
// Take a stage list, and remove all stages matching a set of keys
|
|
42
|
-
type DropStages<List extends StageList, Dropped extends string> = {
|
|
43
|
-
[Index in keyof List]: List[Index]['key'] extends Dropped
|
|
44
|
-
? never
|
|
45
|
-
: List[Index]
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Take a stage list, and keep only the stages matching a set of keys
|
|
49
|
-
type KeepStages<List extends StageList, Allowed extends string> = {
|
|
50
|
-
[Index in keyof List]: List[Index]['key'] extends Allowed
|
|
51
|
-
? List[Index]
|
|
52
|
-
: never
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Parse a stage list to extract all the stages matching a key
|
|
56
|
-
type GetStage<
|
|
57
|
-
List extends StageList,
|
|
58
|
-
Key extends MethodName,
|
|
59
|
-
Union = List[number],
|
|
60
|
-
> = Union extends { key: Key; value: infer U; stages: infer S }
|
|
61
|
-
? { key: Key; value: U; stages: S }
|
|
62
|
-
: never
|
|
63
|
-
|
|
64
|
-
// Parse a stage list to extract the collapsed value for a given stage key
|
|
65
|
-
type GetStageValue<
|
|
66
|
-
List extends StageList,
|
|
67
|
-
Key extends MethodName,
|
|
68
|
-
> = UnionToIntersection<GetStage<List, Key>['value']>
|
|
69
|
-
|
|
70
|
-
// Collapse a complete stage list into an argument object
|
|
71
|
-
// Use the deep `extends infer U` method to get a clean object in tooltips
|
|
72
|
-
type ComputeArgs<
|
|
73
|
-
Stages extends StageList,
|
|
74
|
-
Limit extends string,
|
|
75
|
-
Union = Stages[number],
|
|
76
|
-
Intersection = UnionToIntersection<
|
|
77
|
-
Union extends { key: infer Key; value: infer Value }
|
|
78
|
-
? { [key in Key extends string ? Key : never]: Value }
|
|
79
|
-
: never
|
|
80
|
-
>,
|
|
81
|
-
> = Pick<
|
|
82
|
-
Intersection,
|
|
83
|
-
Limit extends keyof Intersection ? Limit : never
|
|
84
|
-
|
|
85
|
-
// Deeply spread the object for cleaner type tooltips
|
|
86
|
-
> extends infer U
|
|
87
|
-
? {
|
|
88
|
-
[key in keyof U]: U[key] extends Record<string, unknown>
|
|
89
|
-
? U[key] extends infer V
|
|
90
|
-
? { [key in keyof V]: V[key] }
|
|
91
|
-
: never
|
|
92
|
-
: U[key]
|
|
93
|
-
}
|
|
94
|
-
: never
|
|
95
|
-
|
|
96
|
-
// Check if a custom transform exists for the given argument, and apply
|
|
97
|
-
// it to the current value if there is
|
|
98
|
-
type TransformArg<
|
|
99
|
-
Value,
|
|
100
|
-
Symbol
|
|
101
|
-
> = Symbol extends keyof ModularStageTransform<Value>
|
|
102
|
-
? ModularStageTransform<Value>[Symbol]
|
|
103
|
-
: Value
|
|
104
|
-
|
|
105
|
-
// Map all computed arguments against the methods map to convert
|
|
106
|
-
// from the stage key to the wanted field name
|
|
107
|
-
// Use the deep `extends infer U` method to get a clean object in tooltips
|
|
108
|
-
type MapArgs<
|
|
109
|
-
Stages extends StageList,
|
|
110
|
-
Limit extends string,
|
|
111
|
-
Methods extends MethodRecord,
|
|
112
|
-
Props,
|
|
113
|
-
Args = ComputeArgs<Stages, Limit>,
|
|
114
|
-
> = UnionToIntersection<
|
|
115
|
-
// Start by injecting the original props
|
|
116
|
-
| { props: Props, children: Props extends { children: infer U } ? U : never }
|
|
117
|
-
// Map over all configured methods
|
|
118
|
-
| {
|
|
119
|
-
[key in keyof Methods]: key extends keyof Args // Check if an arg exists for the given method
|
|
120
|
-
? Methods[key] extends MethodEntry
|
|
121
|
-
? {
|
|
122
|
-
// Extract the field name from the method
|
|
123
|
-
[k in Methods[key]['field']]: TransformArg<
|
|
124
|
-
Args[key],
|
|
125
|
-
Methods[key]['symbol']
|
|
126
|
-
>
|
|
127
|
-
}
|
|
128
|
-
: never
|
|
129
|
-
: // Set to never if the arg does not exist
|
|
130
|
-
never
|
|
131
|
-
}[keyof Methods]
|
|
132
|
-
|
|
133
|
-
// Deeply spread the object for cleaner type tooltips
|
|
134
|
-
> extends infer U
|
|
135
|
-
? {
|
|
136
|
-
[key in keyof U]: U[key] extends Record<string, unknown>
|
|
137
|
-
? U[key] extends infer V
|
|
138
|
-
? { [key in keyof V]: V[key] }
|
|
139
|
-
: never
|
|
140
|
-
: U[key]
|
|
141
|
-
}
|
|
142
|
-
: never
|
|
143
|
-
|
|
144
|
-
type ModularExtension<
|
|
145
|
-
Props,
|
|
146
|
-
Methods extends MethodRecord,
|
|
147
|
-
Stages extends StageList,
|
|
148
|
-
> = {
|
|
149
|
-
[key in keyof Methods]: (Methods[key] extends MethodEntry
|
|
150
|
-
? Methods[key]
|
|
151
|
-
: never)['restrict'] extends undefined
|
|
152
|
-
? <
|
|
153
|
-
// Cast the method key to a method name
|
|
154
|
-
Key extends key extends MethodName ? key : never,
|
|
155
|
-
// Extract the current method
|
|
156
|
-
Method extends Methods[Key] extends MethodEntry ? Methods[Key] : never,
|
|
157
|
-
// If the mode is not 'multiple', get any previous value used
|
|
158
|
-
// for the stage
|
|
159
|
-
Prev extends Method['multiple'] extends true
|
|
160
|
-
? never
|
|
161
|
-
: GetStageValue<Stages, Key>,
|
|
162
|
-
// Find the stages occurring before the first instance of the current
|
|
163
|
-
// stage, in order to limit the arguments to those defined before the
|
|
164
|
-
// stage. This is needed for 'single' mode stages that are called
|
|
165
|
-
// multiple time.
|
|
166
|
-
Limit extends Method['multiple'] extends true // Ignore for 'multiple' stages
|
|
167
|
-
? Stages[number]['key']
|
|
168
|
-
: [GetStage<Stages, Key>] extends [never] // Ignore if it's the first time we see the stage
|
|
169
|
-
? Stages[number]['key']
|
|
170
|
-
: GetStage<Stages, Key>['stages'],
|
|
171
|
-
// Compute the kept stages by dropping all references to current stage
|
|
172
|
-
// for multiple mode, or keeping all previous stages for single mode
|
|
173
|
-
KeptStages extends Method['multiple'] extends true
|
|
174
|
-
? DropStages<Stages, Key>
|
|
175
|
-
: Stages,
|
|
176
|
-
// Get the value to use or infer, restricting it to any
|
|
177
|
-
// configured restriction or previously used values
|
|
178
|
-
Value extends [Prev] extends [never]
|
|
179
|
-
? [Method['restrict']] extends [never]
|
|
180
|
-
? unknown
|
|
181
|
-
: Method['restrict']
|
|
182
|
-
: Prev,
|
|
183
|
-
>(
|
|
184
|
-
// A stage accepts either a direct value or a function (hook) generating the value
|
|
185
|
-
value?:
|
|
186
|
-
| Value
|
|
187
|
-
| ((args: MapArgs<Stages, Limit, Methods, Props>) => Value | void),
|
|
188
|
-
) => Modular<Props, Methods, AppendStage<KeptStages, Key, Value>>
|
|
189
|
-
: <
|
|
190
|
-
// Cast the method key to a method name
|
|
191
|
-
Key extends key extends MethodName ? key : never,
|
|
192
|
-
// Extract the current method
|
|
193
|
-
Method extends Methods[Key] extends MethodEntry ? Methods[Key] : never,
|
|
194
|
-
// If the mode is not 'multiple', get any previous value used
|
|
195
|
-
// for the stage
|
|
196
|
-
Prev extends Method['multiple'] extends true
|
|
197
|
-
? never
|
|
198
|
-
: GetStageValue<Stages, Key>,
|
|
199
|
-
// Find the stages occurring before the first instance of the current
|
|
200
|
-
// stage, in order to limit the arguments to those defined before the
|
|
201
|
-
// stage. This is needed for 'single' mode stages that are called
|
|
202
|
-
// multiple time.
|
|
203
|
-
Limit extends Method['multiple'] extends true // Ignore for 'multiple' stages
|
|
204
|
-
? Stages[number]['key']
|
|
205
|
-
: [GetStage<Stages, Key>] extends [never] // Ignore if it's the first time we see the stage
|
|
206
|
-
? Stages[number]['key']
|
|
207
|
-
: GetStage<Stages, Key>['stages'],
|
|
208
|
-
// Compute the kept stages by dropping all references to current stage
|
|
209
|
-
// for multiple mode, or keeping all previous stages for single mode
|
|
210
|
-
KeptStages extends Method['multiple'] extends true
|
|
211
|
-
? DropStages<Stages, Key>
|
|
212
|
-
: Stages,
|
|
213
|
-
// Get the value to use or infer, restricting it to any
|
|
214
|
-
// configured restriction or previously used values
|
|
215
|
-
Value extends [Prev] extends [never]
|
|
216
|
-
? [Method['restrict']] extends [never]
|
|
217
|
-
? unknown
|
|
218
|
-
: Method['restrict']
|
|
219
|
-
: Prev,
|
|
220
|
-
>(
|
|
221
|
-
// A stage accepts either a direct value or a function (hook) generating the value
|
|
222
|
-
value:
|
|
223
|
-
| Value
|
|
224
|
-
| ((args: MapArgs<Stages, Limit, Methods, Props>) => Value),
|
|
225
|
-
) => Modular<Props, Methods, AppendStage<KeptStages, Key, Value>>
|
|
226
|
-
} & {
|
|
227
|
-
// Create a new component using the same stages as the current component
|
|
228
|
-
// up to a certain point
|
|
229
|
-
atStage<
|
|
230
|
-
// Key of the stage to keep to
|
|
231
|
-
Key extends Stages[number]['key'],
|
|
232
|
-
// List of stages up to the one referenced by the key
|
|
233
|
-
KeptStages extends KeepStages<
|
|
234
|
-
Stages,
|
|
235
|
-
GetStage<Stages, Key>['stages'] | Key
|
|
236
|
-
>,
|
|
237
|
-
>(
|
|
238
|
-
stage: Key,
|
|
239
|
-
): Modular<Props, Methods, KeptStages>
|
|
240
|
-
// Generate a hook instead of a component, returning the generated arguments
|
|
241
|
-
asHook(): Props extends {}
|
|
242
|
-
? () => MapArgs<Stages, Stages[number]['key'], Methods, Props>
|
|
243
|
-
: (props: Props) => MapArgs<Stages, Stages[number]['key'], Methods, Props>
|
|
244
|
-
// Overload the asHook function to allow taking in a field from the generated arguments,
|
|
245
|
-
// and returning only the value from this field
|
|
246
|
-
asHook<
|
|
247
|
-
Field extends keyof MapArgs<Stages, Stages[number]['key'], Methods, Props>,
|
|
248
|
-
>(
|
|
249
|
-
field: Field,
|
|
250
|
-
): Props extends {}
|
|
251
|
-
? () => MapArgs<Stages, Stages[number]['key'], Methods, Props>[Field]
|
|
252
|
-
: (
|
|
253
|
-
props: Props,
|
|
254
|
-
) => MapArgs<Stages, Stages[number]['key'], Methods, Props>[Field]
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Type used for describing a ModularComponent. In essence, it is a FunctionComponent
|
|
258
|
-
// with all the factories methods appended.
|
|
259
|
-
// In this type, we strongly-type all factory methods and the enhanced returned component
|
|
260
|
-
// by keeping track of all the previous stages through a stage-list tuple
|
|
261
|
-
export type Modular<
|
|
262
|
-
// The props are set and are invariant for the component, but the `props` argument
|
|
263
|
-
// itself can be extended
|
|
264
|
-
Props,
|
|
265
|
-
// List of all methods available for the component, won't change as the component
|
|
266
|
-
// is built but depends on the factory that started the build
|
|
267
|
-
Methods extends MethodRecord,
|
|
268
|
-
// Finally, the list of stages that will be appended as methods are called
|
|
269
|
-
Stages extends StageList,
|
|
270
|
-
> =
|
|
271
|
-
// At its core, the ModularComponent is a normal FunctionComponent taking
|
|
272
|
-
// the original props, extended with additional methods
|
|
273
|
-
FunctionComponent<Props> & ModularExtension<Props, Methods, Stages>
|
|
274
|
-
|
|
275
|
-
/* Exposed interfaces used for extending functionality */
|
|
276
|
-
|
|
277
|
-
// Add a value transformation for a given stage. The T type is the
|
|
278
|
-
// original type of the value passed to the stage.
|
|
279
|
-
export interface ModularStageTransform<T> {}
|