inferred-types 0.33.1 → 0.33.2

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.
Files changed (145) hide show
  1. package/.vscode/settings.json +1 -0
  2. package/dist/index.d.ts +1182 -1125
  3. package/dist/index.js +73 -182
  4. package/dist/index.mjs +70 -175
  5. package/package.json +16 -15
  6. package/src/{utility/errors → errors}/ReadOnlyViolation.ts +0 -0
  7. package/src/{utility/errors → errors}/index.ts +0 -0
  8. package/src/index.ts +1 -3
  9. package/src/{utility → runtime}/README.md +0 -0
  10. package/src/{utility → runtime}/api/api.ts +0 -0
  11. package/src/{utility → runtime}/api/index.ts +0 -0
  12. package/src/{utility/modelling → runtime/builders}/Model.ts +0 -0
  13. package/src/runtime/builders/url.ts +15 -0
  14. package/src/{utility/boolean-logic → runtime/combinators}/and.ts +0 -0
  15. package/src/{utility/boolean-logic → runtime/combinators}/filter.ts +0 -0
  16. package/src/{utility/boolean-logic → runtime/combinators}/index.ts +0 -0
  17. package/src/{utility/boolean-logic → runtime/combinators}/not.ts +0 -0
  18. package/src/{utility/boolean-logic → runtime/combinators}/or.ts +0 -0
  19. package/src/{utility → runtime}/createFnWithProps.ts +0 -0
  20. package/src/{utility → runtime}/dictionary/arrayToKeyLookup.ts +0 -0
  21. package/src/{utility → runtime}/dictionary/defineProperties.ts +0 -0
  22. package/src/{utility → runtime}/dictionary/dictArr.ts +0 -0
  23. package/src/{utility → runtime}/dictionary/dictionaryTransform.ts +0 -0
  24. package/src/{utility → runtime}/dictionary/entries.ts +0 -0
  25. package/src/{utility → runtime}/dictionary/index.ts +0 -0
  26. package/src/{utility → runtime}/dictionary/kv/dictToKv.ts +1 -1
  27. package/src/{utility → runtime}/dictionary/kv/filterDictArray.ts +1 -1
  28. package/src/{utility → runtime}/dictionary/kv/index.ts +0 -0
  29. package/src/{utility → runtime}/dictionary/kv/kv.ts +0 -0
  30. package/src/{utility → runtime}/dictionary/kv/kvToDict.ts +0 -0
  31. package/src/{utility → runtime}/dictionary/mapTo.ts +0 -0
  32. package/src/{utility → runtime}/dictionary/mapValues.ts +0 -0
  33. package/src/{utility → runtime}/dictionary/merge.ts +0 -0
  34. package/src/{utility → runtime}/dictionary/strArrayToDict.ts +0 -0
  35. package/src/{utility → runtime}/index.ts +1 -3
  36. package/src/{utility → runtime}/keys.ts +0 -0
  37. package/src/{utility → runtime}/lists/asArray.ts +0 -0
  38. package/src/{utility → runtime}/lists/groupBy.ts +0 -0
  39. package/src/{utility → runtime}/lists/index.ts +0 -0
  40. package/src/{utility → runtime}/literals/ExplicitFunction.ts +0 -0
  41. package/src/runtime/literals/Suggest.ts +19 -0
  42. package/src/{utility → runtime}/literals/arrayToObject.ts +0 -0
  43. package/src/runtime/literals/box.ts +77 -0
  44. package/src/{utility → runtime}/literals/defineType.ts +0 -0
  45. package/src/{utility → runtime}/literals/identity.ts +0 -0
  46. package/src/{utility → runtime}/literals/index.ts +2 -0
  47. package/src/{utility → runtime}/literals/literal.ts +0 -0
  48. package/src/{utility → runtime}/ruleset.ts +0 -0
  49. package/src/{utility → runtime}/runtime/README.md +0 -0
  50. package/src/{utility → runtime}/runtime/condition.ts +0 -0
  51. package/src/{utility → runtime}/runtime/index.ts +1 -2
  52. package/src/{utility → runtime}/runtime/type.ts +1 -1
  53. package/src/{utility → runtime}/runtime/withValue.ts +0 -0
  54. package/src/{utility → runtime}/state/Configurator.ts +0 -0
  55. package/src/{utility → runtime}/state/FluentConfigurator.ts +0 -0
  56. package/src/{utility → runtime}/state/index.ts +0 -0
  57. package/src/{utility/runtime → runtime/type-checks}/ifTypeOf.ts +0 -0
  58. package/src/{utility/runtime/conditions → runtime/type-checks}/index.ts +0 -0
  59. package/src/{utility/runtime/conditions → runtime/type-checks}/isArray.ts +0 -0
  60. package/src/{utility/runtime/conditions → runtime/type-checks}/isBoolean.ts +0 -0
  61. package/src/{utility/runtime/conditions → runtime/type-checks}/isFalse.ts +0 -0
  62. package/src/{utility/runtime/conditions → runtime/type-checks}/isFunction.ts +11 -2
  63. package/src/{utility/runtime/conditions → runtime/type-checks}/isNull.ts +0 -0
  64. package/src/{utility/runtime/conditions → runtime/type-checks}/isNumber.ts +0 -0
  65. package/src/{utility/runtime/conditions → runtime/type-checks}/isObject.ts +1 -1
  66. package/src/{utility/runtime/conditions → runtime/type-checks}/isString.ts +13 -5
  67. package/src/{utility/runtime/conditions → runtime/type-checks}/isSymbol.ts +0 -0
  68. package/src/{utility/runtime/conditions → runtime/type-checks}/isTrue.ts +1 -1
  69. package/src/{utility/runtime/conditions → runtime/type-checks}/isUndefined.ts +1 -1
  70. package/src/runtime/type-checks/startsWith.ts +109 -0
  71. package/src/{shared → runtime}/valueTypes.ts +0 -0
  72. package/src/types/FunctionType.ts +12 -2
  73. package/src/types/Mutable.ts +1 -1
  74. package/src/types/alphabetic/Url.ts +29 -0
  75. package/src/types/alphabetic/alpha-characters.ts +8 -0
  76. package/src/types/alphabetic/index.ts +1 -0
  77. package/src/types/dictionary/MapTo.ts +2 -2
  78. package/src/types/index.ts +2 -2
  79. package/src/types/lists/AfterFirst.ts +10 -0
  80. package/src/types/lists/First.ts +8 -0
  81. package/src/types/lists/FirstString.ts +4 -0
  82. package/src/types/lists/Split.ts +21 -0
  83. package/src/types/lists/index.ts +4 -0
  84. package/src/types/ruleset-types.ts +1 -1
  85. package/src/types/type-checks/EndsWith.ts +22 -0
  86. package/src/types/{TypeInfo → type-checks}/Extends.ts +0 -0
  87. package/src/types/{TypeInfo → type-checks}/Includes.ts +0 -0
  88. package/src/types/{TypeInfo → type-checks}/IsBooleanLiteral.ts +0 -0
  89. package/src/types/{TypeInfo → type-checks}/IsLiteral.ts +0 -0
  90. package/src/types/{TypeInfo → type-checks}/IsNumericLiteral.ts +0 -0
  91. package/src/types/{TypeInfo → type-checks}/IsScalar.ts +0 -0
  92. package/src/types/{TypeInfo → type-checks}/IsStringLiteral.ts +2 -6
  93. package/src/types/{TypeInfo → type-checks}/IsUndefined.ts +0 -0
  94. package/src/types/type-checks/StartsWith.ts +43 -0
  95. package/src/types/{TypeInfo → type-checks}/TypeDefault.ts +1 -1
  96. package/src/types/{TypeInfo → type-checks}/index.ts +3 -1
  97. package/src/types/{TypeInfo/IsObject.ts → type-checks/object.ts} +0 -0
  98. package/src/types/type-checks/string.ts +21 -0
  99. package/src/types/type-conversion/TupleToUnion.ts +1 -3
  100. package/tests/ExplicitFunction-spec.ts +1 -1
  101. package/tests/arrayToKeyLookup-spec.ts +1 -1
  102. package/tests/arrayToObject-spec.ts +1 -1
  103. package/tests/boolean-logic/boolean.spec.ts +1 -1
  104. package/tests/boolean-logic/filter.spec.ts +1 -1
  105. package/tests/defineType-spec.ts +1 -1
  106. package/tests/dictionary/Get.spec.ts +1 -1
  107. package/tests/dictionary/TypeDefault.test.ts +2 -2
  108. package/tests/dictionary/mapTo.test.ts +1 -1
  109. package/tests/dictionary/merge.test.ts +1 -1
  110. package/tests/dictionaryTransform-spec.ts +1 -1
  111. package/tests/ifTypeOf-spec.ts +3 -2
  112. package/tests/kv/dict-to-kv-and-back.spec.ts +2 -2
  113. package/tests/kv/entries-spec.ts +1 -1
  114. package/tests/kv/keys.spec.ts +1 -1
  115. package/tests/kv/kv-spec.ts +1 -1
  116. package/tests/lists/First.test.ts +43 -0
  117. package/tests/lists/Split.test.ts +29 -0
  118. package/tests/lists/asArray.test.ts +1 -1
  119. package/tests/lists/dictArr.test.ts +1 -1
  120. package/tests/literal-spec.ts +1 -1
  121. package/tests/{string-literals → literals}/AllCaps.spec.ts +0 -0
  122. package/tests/{string-literals → literals}/CamelCase.spec.ts +0 -0
  123. package/tests/{string-literals → literals}/Dasherize.spec.ts +0 -0
  124. package/tests/{string-literals → literals}/HasUppercase.spec.ts +0 -0
  125. package/tests/{string-literals → literals}/PascalCase.spec.ts +0 -0
  126. package/tests/{string-literals → literals}/SnakeCase.spec.ts +0 -0
  127. package/tests/literals/box.test.ts +77 -0
  128. package/tests/{string-literals → literals}/whitespace-capture.spec.ts +0 -0
  129. package/tests/mapValues-spec.ts +1 -1
  130. package/tests/runtime/condition.spec.ts +1 -1
  131. package/tests/runtime/if-is.spec.ts +158 -2
  132. package/tests/runtime/type.spec.ts +1 -1
  133. package/tests/strArrayToDict-spec.ts +1 -1
  134. package/tests/withValue.spec.ts +1 -1
  135. package/vitest.config.ts +2 -5
  136. package/src/Mutation/MutationFunction.ts +0 -26
  137. package/src/Mutation/MutationIdentity.ts +0 -36
  138. package/src/Mutation/index.ts +0 -14
  139. package/src/shared/README.md +0 -3
  140. package/src/shared/index.ts +0 -15
  141. package/src/shared/randomString.ts +0 -5
  142. package/src/shared/uuid.ts +0 -5
  143. package/src/types/First.ts +0 -4
  144. package/src/utility/modelling/index.ts +0 -12
  145. package/tests/MutationIdentity-spec.ts +0 -25
package/dist/index.d.ts CHANGED
@@ -1,95 +1,11 @@
1
- /**
2
- * **MutationIdentity**
3
- *
4
- * Defines a function which is passed a state `T` and returns a function with
5
- * an arbitrary -- but strongly typed -- set of parameters `P` which _must_ return
6
- * the same state `T` back.
7
- *
8
- * This allows `T` to be mutated by a relatively unconstrained set of mutation functions with the
9
- * sole guarentee that the form `T` is preserved.
10
- */
11
- declare type MutationIdentity<T, P extends any[]> = (state: T) => (...args: P) => T;
12
- /**
13
- * **MutationIdentity**
14
- *
15
- * A function which strongly types the construction of a `MutationIdentity`
16
- * higher-order function to be built. Usage:
17
- *
18
- * - The structure of the _state_ is defined in the first call as `T`
19
- * - The interior function than defines a mutation function which implicitly
20
- * defines the calling signature as `P` but is required to return the identity state
21
- * structure `T`.
22
- *
23
- * ```ts
24
- * type State = { foo: number, bar: number };
25
- * const incr = MutationIdentity<State>()(
26
- * s => () => {...s, foo: s.foo++}
27
- * );
28
- * ```
29
- */
30
- declare function MutationIdentity<T>(): <M extends MutationIdentity<T, P>, P extends any[]>(m: M) => M;
31
-
32
- declare type MutationFunction<T extends any, P extends any[]> = (...args: P) => T;
33
- /**
34
- * **MutationFunction**
35
- *
36
- * Given a `MutationIdentity` higher-order function to work with, _this_ higher order expression
37
- * allows you to specify the structure of "state" `T` with the first function call; the
38
- * remaining function then serves as a strongly typed way to do partial application and get
39
- * back just the _mutation function_ responsible for changing the state. The mutation function
40
- * will take the form of:
41
- *
42
- * ```ts
43
- * const fn: (...args: P) => T = MutationFunction<T>()(mutationIdentity);
44
- * ```
45
- */
46
- declare function createMutationFunction<T extends any>(state: T): <M extends MutationIdentity<T, P>, P extends any[]>(mutationIdentity: M) => (...args: P) => T;
47
-
48
- declare function randomString(): string;
49
-
50
- declare function uuid(): string;
51
-
52
- /**
53
- * A union of types used in conjunction with the `literalValues()` function
54
- * to produce a _narrow_ type definition of a passed in dictionary object.
55
- */
56
- declare type Narrowable = string | number | boolean | symbol | object | undefined | void | null | {};
57
-
58
- declare type ValueTuple = [type: any, narrowable: boolean];
59
- /**
60
- * An API surface for choosing a **type** which is defined for run-time
61
- * use but is translatable to the type system as well.
62
- */
63
- declare type ValueTypes = {
64
- string: [string, false];
65
- boolean: [];
66
- };
67
- declare const valueTypes: {
68
- string: [string, false];
69
- boolean: [boolean, false];
70
- number: [number, false];
71
- function: [Function, false];
72
- object: [Record<string, any>, false];
73
- array: <T extends unknown>(arr?: T[]) => [T[], false];
74
- null: [null, false];
75
- symbol: [Symbol, false];
76
- undefined: [undefined, false];
77
- true: [true, true];
78
- false: [false, true];
79
- /** pass in a literal type */
80
- literal: <N extends Narrowable, T_1 extends string | number | boolean | symbol | Record<any, N> | null | undefined>(v: T_1) => [T_1, true];
81
- literalArray: <N_1 extends Narrowable, T_2 extends string | number | boolean | symbol | Record<any, N_1> | null | undefined>(arr: T_2[]) => (boolean | T_2[])[];
82
- };
83
- declare type ValueTypeFunc<N extends Narrowable, T extends Record<any, N> | number | string | boolean | symbol | null | Function> = (v: ValueTypes) => [T, boolean];
84
-
85
- declare type ApiFunction<P extends any[], R extends any> = (...args: P) => R;
86
- declare type FluentFunction<P extends any[], R extends any> = (...args: P) => R;
87
- declare type ApiValue<V extends any> = V;
1
+ type ApiFunction<P extends any[], R extends any> = (...args: P) => R;
2
+ type FluentFunction<P extends any[], R extends any> = (...args: P) => R;
3
+ type ApiValue<V extends any> = V;
88
4
  /**
89
5
  * Expresses the API in a structured manner while making distinction
90
6
  * between a function endpoint and a _fluent_ function endpoint.
91
7
  */
92
- declare type Api<T extends object> = {
8
+ type Api<T extends object> = {
93
9
  [K in keyof T]: T[K] extends (...args: any) => T ? FluentFunction<Parameters<T[K]>, ReturnType<T[K]>> : T[K] extends (...args: any) => any ? ApiFunction<Parameters<T[K]>, ReturnType<T[K]>> : ApiValue<T[K]>;
94
10
  };
95
11
 
@@ -97,7 +13,7 @@ declare type Api<T extends object> = {
97
13
  * Define a class constructor; allowing strong typing for constructor's parameters
98
14
  * and the returned class structure.
99
15
  */
100
- declare type Constructor<Ctor extends any[], Klass extends any> = new (...props: Ctor) => Klass;
16
+ type Constructor<Ctor extends any[], Klass extends any> = new (...props: Ctor) => Klass;
101
17
 
102
18
  /**
103
19
  * Provides the values of an Typescript **enum**:
@@ -112,30 +28,40 @@ declare type Constructor<Ctor extends any[], Klass extends any> = new (...props:
112
28
  *
113
29
  * **Note:** combine with `Numeric` to get number based indexes
114
30
  */
115
- declare type EnumValues<T extends string | number> = `${T}`;
31
+ type EnumValues<T extends string | number> = `${T}`;
116
32
 
117
33
  /**
118
34
  * Recursively goes over an object based structure and tries to reduce
119
35
  * it down to just a simple key/value type.
120
36
  */
121
- declare type ExpandRecursively<T> = T extends object ? T extends (...args: any[]) => any ? T : {
37
+ type ExpandRecursively<T> = T extends object ? T extends (...args: any[]) => any ? T : {
122
38
  [K in keyof T]: ExpandRecursively<T[K]>;
123
39
  } : T;
124
40
 
125
41
  /**
126
42
  * Returns the first values type in an array of values
127
43
  */
128
- declare type First<T extends any[]> = T[0] extends T[number] ? T[0] : never;
44
+ type First<T extends readonly any[]> = T[0] extends T[number] ? T[0] : never;
45
+ type FirstOrUndefined<T extends unknown> = T extends [unknown, ...[unknown]] ? First<T> : undefined;
129
46
 
130
47
  /**
131
- * Defines a function type.
48
+ * **FunctionType**
49
+ *
50
+ * Provides a way to correctly match for regular functions _and_ functions which
51
+ * also have a dictionary hash alongside the root function.
132
52
  *
133
53
  * - without the generic `T` specified it simply matches correctly on both plain functions as well as functions which also have properties on them (this is consistent to how runtime's `typeof` operator works)
134
54
  * - with the generic you can specify the shape of the key/values
135
55
  */
136
- declare type FunctionType<T extends {} = {}> = {} extends T ? Function | (Function & {
56
+ type FunctionType<T extends {} = {}> = {} extends T ? Function | (Function & {
137
57
  [key: string]: any;
138
58
  }) : Function | (Function & T);
59
+ /**
60
+ * **FnShape**
61
+ *
62
+ * Simple way to express the shape of a function's arguments and return type.
63
+ */
64
+ type FnShape<A extends any[] = any[], R extends any = any> = (...args: A) => R;
139
65
 
140
66
  /**
141
67
  * Provides a unary condition for the type system:
@@ -146,7 +72,7 @@ declare type FunctionType<T extends {} = {}> = {} extends T ? Function | (Functi
146
72
  * type F = If<false, "a", "b">;
147
73
  * ```
148
74
  */
149
- declare type If<C extends boolean, T, F> = C extends T ? C | F : never;
75
+ type If<C extends boolean, T, F> = C extends T ? C | F : never;
150
76
 
151
77
  /**
152
78
  * **Include<T, U, L>**
@@ -163,7 +89,7 @@ declare type If<C extends boolean, T, F> = C extends T ? C | F : never;
163
89
  * type L2 = Include<typeof foo, "foo", true>;
164
90
  * ```
165
91
  */
166
- declare type Include<T, U, L extends boolean = false> = L extends true ? T extends U ? U extends T ? T : never : never : T extends U ? T : never;
92
+ type Include<T, U, L extends boolean = false> = L extends true ? T extends U ? U extends T ? T : never : never : T extends U ? T : never;
167
93
 
168
94
  /**
169
95
  * A "KeyedRecord" is intended to store a value without
@@ -178,7 +104,7 @@ declare type Include<T, U, L extends boolean = false> = L extends true ? T exten
178
104
  * const song: KeyedRecord = { __key: "song", song: XXX }
179
105
  * ```
180
106
  */
181
- declare type KeyedRecord<K extends string, V extends any, T extends {
107
+ type KeyedRecord<K extends string, V extends any, T extends {
182
108
  __key: K;
183
109
  } = {
184
110
  __key: K;
@@ -204,7 +130,7 @@ declare type KeyedRecord<K extends string, V extends any, T extends {
204
130
  * type K = Keys<typeof t2>;
205
131
  * ```
206
132
  */
207
- declare type Keys<T extends Record<string, any> | readonly string[], W extends string | undefined = undefined> = T extends readonly string[] ? W extends string ? Exclude<T[number], W> : T[number] : W extends string ? Exclude<keyof T & string, W> : keyof T & string;
133
+ type Keys<T extends Record<string, any> | readonly string[], W extends string | undefined = undefined> = T extends readonly string[] ? W extends string ? Exclude<T[number], W> : T[number] : W extends string ? Exclude<keyof T & string, W> : keyof T & string;
208
134
 
209
135
  /**
210
136
  * Utility type which returns the length of an array literal
@@ -213,7 +139,7 @@ declare type Keys<T extends Record<string, any> | readonly string[], W extends s
213
139
  * type Three = Length<[ "a", "b", "c" ]>;
214
140
  * ```
215
141
  */
216
- declare type Length<T extends readonly any[]> = T["length"];
142
+ type Length<T extends readonly any[]> = T["length"];
217
143
 
218
144
  /**
219
145
  * Converts a Tuple type into a _union_ of the tuple elements
@@ -223,24 +149,24 @@ declare type Length<T extends readonly any[]> = T["length"];
223
149
  * type U = TupleToUnion<typeof arr>;
224
150
  * ```
225
151
  */
226
- declare type TupleToUnion<T> = Mutable<T> extends any[] ? Mutable<T>[number] : never;
152
+ type TupleToUnion<T> = T extends readonly any[] ? T[number] : never;
227
153
 
228
154
  /**
229
155
  * UnionToIntersection<{ foo: string } | { bar: string }> =
230
156
  * { foo: string } & { bar: string }.
231
157
  */
232
- declare type UnionToIntersection<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;
158
+ type UnionToIntersection<U> = (U extends unknown ? (arg: U) => 0 : never) extends (arg: infer I) => 0 ? I : never;
233
159
 
234
160
  /**
235
161
  * LastInUnion<1 | 2> = 2.
236
162
  */
237
- declare type LastInUnion<U> = UnionToIntersection<U extends unknown ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L : never;
163
+ type LastInUnion<U> = UnionToIntersection<U extends unknown ? (x: U) => 0 : never> extends (x: infer L) => 0 ? L : never;
238
164
  /**
239
165
  * UnionToTuple<1 | 2> = [1, 2].
240
166
  */
241
- declare type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never] ? [] : [...UnionToTuple<Exclude<U, Last>>, Last];
167
+ type UnionToTuple<U, Last = LastInUnion<U>> = [U] extends [never] ? [] : [...UnionToTuple<Exclude<U, Last>>, Last];
242
168
 
243
- declare type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
169
+ type Widen<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
244
170
 
245
171
  /**
246
172
  * **IsBooleanLiteral**
@@ -248,13 +174,13 @@ declare type Widen<T> = T extends string ? string : T extends number ? number :
248
174
  * Type utility which returns true/false if the boolean value is a _boolean literal_ versus
249
175
  * just the wider _boolean_ type.
250
176
  */
251
- declare type IsBooleanLiteral<T extends boolean> = boolean extends T ? false : true;
177
+ type IsBooleanLiteral<T extends boolean> = boolean extends T ? false : true;
252
178
  /**
253
179
  * **IfBooleanLiteral**
254
180
  *
255
181
  * Branch utility which returns `IF` type when `T` is a boolean literal and `ELSE` otherwise
256
182
  */
257
- declare type IfBooleanLiteral<T extends boolean, IF, ELSE> = IsBooleanLiteral<T> extends true ? IF : ELSE;
183
+ type IfBooleanLiteral<T extends boolean, IF, ELSE> = IsBooleanLiteral<T> extends true ? IF : ELSE;
258
184
 
259
185
  /**
260
186
  * **IsStringLiteral**
@@ -262,13 +188,13 @@ declare type IfBooleanLiteral<T extends boolean, IF, ELSE> = IsBooleanLiteral<T>
262
188
  * Type utility which returns true/false if the string a _string literal_ versus
263
189
  * just the _string_ type.
264
190
  */
265
- declare type IsStringLiteral<T> = T extends string ? string extends T ? false : true : false;
191
+ type IsStringLiteral<T> = [T] extends [string] ? (string extends T ? false : true) : false;
266
192
  /**
267
193
  * **IfStringLiteral**
268
194
  *
269
195
  * Branch utility which returns `IF` type when `T` is a string literal and `ELSE` otherwise
270
196
  */
271
- declare type IfStringLiteral<T extends string, IF, ELSE> = IsStringLiteral<T> extends true ? IF : ELSE;
197
+ type IfStringLiteral<T, IF, ELSE> = [IsStringLiteral<T>] extends [true] ? IF : ELSE;
272
198
 
273
199
  /**
274
200
  * **IsNumericLiteral**
@@ -276,13 +202,13 @@ declare type IfStringLiteral<T extends string, IF, ELSE> = IsStringLiteral<T> ex
276
202
  * Type utility which returns true/false if the numeric value a _numeric literal_ versus
277
203
  * just the _number_ type.
278
204
  */
279
- declare type IsNumericLiteral<T extends number> = number extends T ? false : true;
205
+ type IsNumericLiteral<T extends number> = number extends T ? false : true;
280
206
  /**
281
207
  * **IfNumericLiteral**
282
208
  *
283
209
  * Branch utility which returns `IF` type when `T` is a numeric literal and `ELSE` otherwise
284
210
  */
285
- declare type IfNumericLiteral<T extends number, IF, ELSE> = IsNumericLiteral<T> extends true ? IF : ELSE;
211
+ type IfNumericLiteral<T extends number, IF, ELSE> = IsNumericLiteral<T> extends true ? IF : ELSE;
286
212
 
287
213
  /**
288
214
  * **IsLiteral**
@@ -291,7 +217,7 @@ declare type IfNumericLiteral<T extends number, IF, ELSE> = IsNumericLiteral<T>
291
217
  * string, number, or boolean -- is a _literal_ value of that type (true) or
292
218
  * the more generic wide type (false).
293
219
  */
294
- declare type IsLiteral<T> = [T] extends [string] ? IsStringLiteral<T> : [T] extends [boolean] ? IsBooleanLiteral<T> : [T] extends [number] ? IsNumericLiteral<T> : false;
220
+ type IsLiteral<T> = [T] extends [string] ? IsStringLiteral<T> : [T] extends [boolean] ? IsBooleanLiteral<T> : [T] extends [number] ? IsNumericLiteral<T> : false;
295
221
  /**
296
222
  * **IsOptionalLiteral**
297
223
  *
@@ -303,20 +229,20 @@ declare type IsLiteral<T> = [T] extends [string] ? IsStringLiteral<T> : [T] exte
303
229
  * to `true` even when a literal value is in union with _undefined_. If you don't
304
230
  * want to test for the union with _undefined_ use the `IsOptional` utility instead.
305
231
  */
306
- declare type IsOptionalLiteral<T> = [Exclude<T, undefined>] extends [string] ? IsStringLiteral<Exclude<T, undefined>> : [Exclude<T, undefined>] extends [boolean] ? IsBooleanLiteral<Exclude<T, undefined>> : [Exclude<T, undefined>] extends [number] ? IsNumericLiteral<Exclude<T, undefined>> : false;
232
+ type IsOptionalLiteral<T> = [Exclude<T, undefined>] extends [string] ? IsStringLiteral<Exclude<T, undefined>> : [Exclude<T, undefined>] extends [boolean] ? IsBooleanLiteral<Exclude<T, undefined>> : [Exclude<T, undefined>] extends [number] ? IsNumericLiteral<Exclude<T, undefined>> : false;
307
233
  /**
308
234
  * **IfLiteral**
309
235
  *
310
236
  * Branch type utility with return `IF` when `T` is a _literal_ value and `ELSE` otherwise
311
237
  */
312
- declare type IfLiteral<T, IF, ELSE> = IsLiteral<T> extends true ? IF : ELSE;
238
+ type IfLiteral<T, IF, ELSE> = IsLiteral<T> extends true ? IF : ELSE;
313
239
  /**
314
240
  * **IfOptionalLiteral**
315
241
  *
316
242
  * Branch type utility with return `IF` when `T` is a _literal_ value (with possibly
317
243
  * the inclusion of _undefined_); otherwise returns the type `ELSE`
318
244
  */
319
- declare type IfOptionalLiteral<T, IF, ELSE> = IsOptionalLiteral<T> extends true ? IF : ELSE;
245
+ type IfOptionalLiteral<T, IF, ELSE> = IsOptionalLiteral<T> extends true ? IF : ELSE;
320
246
 
321
247
  /**
322
248
  * **Includes<TSource, TValue>**
@@ -328,29 +254,29 @@ declare type IfOptionalLiteral<T, IF, ELSE> = IsOptionalLiteral<T> extends true
328
254
  * no way to know at design-time whether the value includes `TValue` and so it will return
329
255
  * a type of `boolean`.
330
256
  */
331
- declare type Includes<TSource extends string | string[], TValue extends string> = TSource extends string[] ? IsStringLiteral<TupleToUnion<TSource>> extends true ? IsLiteral<TValue> extends true ? TValue extends TupleToUnion<TSource> ? true : false : boolean : boolean : TSource extends string ? IsLiteral<TSource> extends true ? IsLiteral<TValue> extends true ? TSource extends `${string}${TValue}${string}` ? true : false : boolean : boolean : boolean;
257
+ type Includes<TSource extends string | string[], TValue extends string> = TSource extends string[] ? IsStringLiteral<TupleToUnion<TSource>> extends true ? IsLiteral<TValue> extends true ? TValue extends TupleToUnion<TSource> ? true : false : boolean : boolean : TSource extends string ? IsLiteral<TSource> extends true ? IsLiteral<TValue> extends true ? TSource extends `${string}${TValue}${string}` ? true : false : boolean : boolean : boolean;
332
258
 
333
- declare type IsScalar<T> = [T] extends [string] ? true : [T] extends [number] ? true : [T] extends [boolean] ? true : false;
259
+ type IsScalar<T> = [T] extends [string] ? true : [T] extends [number] ? true : [T] extends [boolean] ? true : false;
334
260
  /**
335
261
  * **IfScalar**
336
262
  *
337
263
  * Branch type utility which returns `IF` when `T` is a scalar value and `ELSE` otherwise
338
264
  */
339
- declare type IfScalar<T, IF, ELSE> = IsScalar<T> extends true ? IF : ELSE;
265
+ type IfScalar<T, IF, ELSE> = IsScalar<T> extends true ? IF : ELSE;
340
266
 
341
267
  /**
342
268
  * **Extends**
343
269
  *
344
270
  * Boolean type utility which returns `true` if `E` _extends_ `T`.
345
271
  */
346
- declare type Extends<E, T> = E extends T ? true : false;
272
+ type Extends<E, T> = E extends T ? true : false;
347
273
  /**
348
274
  * **IfExtends**
349
275
  *
350
276
  * Branching type utility which returns type `IF` when `E` _extends_ `T`; otherwise
351
277
  * it will return the type `ELSE`.
352
278
  */
353
- declare type IfExtends<E, T, IF, ELSE> = Extends<E, T> extends true ? IF : ELSE;
279
+ type IfExtends<E, T, IF, ELSE> = Extends<E, T> extends true ? IF : ELSE;
354
280
 
355
281
  /**
356
282
  * Often when mutating the shape of an object you will end up with the union of a number of
@@ -358,21 +284,27 @@ declare type IfExtends<E, T, IF, ELSE> = Extends<E, T> extends true ? IF : ELSE;
358
284
  *
359
285
  * This type utility will cleanup an object and return a simple dictionary definition for it.
360
286
  */
361
- declare type SimplifyObject<T extends {}> = ExpandRecursively<UnionToIntersection<ExpandRecursively<T>>>;
287
+ type SimplifyObject<T extends {}> = ExpandRecursively<UnionToIntersection<ExpandRecursively<T>>>;
288
+
289
+ /**
290
+ * A union of types used in conjunction with the `literalValues()` function
291
+ * to produce a _narrow_ type definition of a passed in dictionary object.
292
+ */
293
+ type Narrowable = string | number | boolean | symbol | object | undefined | void | null | {};
362
294
 
363
295
  /**
364
296
  * **IsUndefined**
365
297
  *
366
298
  * Boolean type utility returns `true` if `T` is undefined; `false` otherwise
367
299
  */
368
- declare type IsUndefined<T extends Narrowable> = T extends undefined ? true : false;
300
+ type IsUndefined<T extends Narrowable> = T extends undefined ? true : false;
369
301
  /**
370
302
  * **IfUndefined**
371
303
  *
372
304
  * Branch utility which returns `IF` type when `T` is an _undefined_ value
373
305
  * otherwise returns `ELSE` type
374
306
  */
375
- declare type IfUndefined<T, IF, ELSE> = IsUndefined<T> extends true ? IF : ELSE;
307
+ type IfUndefined<T, IF, ELSE> = IsUndefined<T> extends true ? IF : ELSE;
376
308
 
377
309
  /**
378
310
  * **TypeDefault**
@@ -393,7 +325,7 @@ declare type IfUndefined<T, IF, ELSE> = IsUndefined<T> extends true ? IF : ELSE;
393
325
  * type DF2 = TypeDefault<typeof i, D>; // `{ foo: "foo"; bar: 99 }`
394
326
  * ```
395
327
  */
396
- declare type TypeDefault<T, D> = IsObject<D> extends true ? IsObject<T> extends true ? SimplifyObject<{
328
+ type TypeDefault<T, D> = IsObject<D> extends true ? IsObject<T> extends true ? SimplifyObject<{
397
329
  [K in keyof D]: K extends keyof T ? TypeDefault<T[K], D[K]> : D[K];
398
330
  }> : IfUndefined<T, // check if T is undefined
399
331
  D, // use D as the type
@@ -408,19 +340,54 @@ Exclude<T, undefined>>, Exclude<T, undefined>>>;
408
340
  *
409
341
  * Boolean type utility used to check whether a type `T` is an object
410
342
  */
411
- declare type IsObject<T> = Mutable<T> extends Record<string, any> ? T extends FunctionType ? false : Mutable<T> extends any[] ? false : true : false;
343
+ type IsObject<T> = Mutable<T> extends Record<string, any> ? T extends FunctionType ? false : Mutable<T> extends any[] ? false : true : false;
412
344
  /**
413
345
  * **IfObject**
414
346
  *
415
347
  * Branch type utility with return `IF` when `T` extends an object type
416
348
  * and `ELSE` otherwise
417
349
  */
418
- declare type IfObject<T, IF, ELSE> = IsObject<T> extends true ? IF : ELSE;
350
+ type IfObject<T, IF, ELSE> = IsObject<T> extends true ? IF : ELSE;
351
+
352
+ /**
353
+ * **StartsWith**<TValue, TStartsWith>
354
+ *
355
+ * A type utility which checks whether `T` _starts with_ the string literal `U`.
356
+ *
357
+ * If both `T` and `U` are string literals then the type system will resolve
358
+ * to a literal `true` or `false` but if either is not a literal that it will
359
+ * just resolve to `boolean` as the value can not be known at design time..
360
+ */
361
+ type StartsWith<TValue extends unknown, TStartsWith extends unknown> = TValue extends string ? TStartsWith extends string ? TValue extends `${TStartsWith}${string}` ? IfStringLiteral<TValue, //
362
+ IfStringLiteral<TStartsWith, true, boolean>, boolean> : IfStringLiteral<TValue, false, boolean> : false : false;
363
+ /**
364
+ * **IfStartsWith**<TValue, TStartsWith, IF, ELSE, MAYBE>
365
+ *
366
+ * Type utility which converts type to `IF` type _if_ TValue _starts with_ `TStartsWith` but
367
+ * otherwise converts type to `ELSE`.
368
+ *
369
+ * Note, that there is also an optional `MAYBE` type
370
+ * which can be stated for cases where TValue or TStartsWith _might_ be the wider `string`
371
+ * type and therefore the type is unknown at design time.
372
+ */
373
+ type IfStartsWith<TValue extends unknown, TStartsWith extends unknown, IF extends Narrowable, ELSE extends Narrowable> = StartsWith<TValue, TStartsWith> extends true ? IF : StartsWith<TValue, TStartsWith> extends false ? ELSE : IF | ELSE;
374
+
375
+ /**
376
+ * **EndsWith**<T,U>
377
+ *
378
+ * A type utility which checks whether `T` _ends with_ the string literal `U`.
379
+ *
380
+ * If both `T` and `U` are string literals then the type system will resolve
381
+ * to a literal `true` or `false` but if either is not a literal that it will
382
+ * just resolve to `boolean` as the value can not be known at design time..
383
+ */
384
+ type EndsWith<T extends unknown, U extends unknown> = T extends string ? U extends string ? T extends `${string}${U}` ? IfStringLiteral<T, //
385
+ IfStringLiteral<U, true, boolean>, boolean> : IfStringLiteral<T, false, boolean> : false : false;
419
386
 
420
387
  /**
421
388
  * Makes a readonly structure mutable
422
389
  */
423
- declare type Mutable<T> = {
390
+ type Mutable<T> = {
424
391
  -readonly [K in keyof T]: IsObject<T[K]> extends true ? Mutable<T[K]> : T[K];
425
392
  };
426
393
 
@@ -436,11 +403,11 @@ declare type Mutable<T> = {
436
403
  *
437
404
  * Note: same as `Exclude`
438
405
  */
439
- declare type Not<T, U> = T extends U ? never : T;
406
+ type Not<T, U> = T extends U ? never : T;
440
407
 
441
- declare type Digital = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
442
- declare type MakeArray<S extends string, T extends any[] = []> = S extends `${T["length"]}` ? T : MakeArray<S, [...T, 0]>;
443
- declare type Multiply10<T extends any[]> = [...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T];
408
+ type Digital = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
409
+ type MakeArray<S extends string, T extends any[] = []> = S extends `${T["length"]}` ? T : MakeArray<S, [...T, 0]>;
410
+ type Multiply10<T extends any[]> = [...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T, ...T];
444
411
  /**
445
412
  * Converts a string literal to a numeric literal
446
413
  * ```ts
@@ -450,7 +417,7 @@ declare type Multiply10<T extends any[]> = [...T, ...T, ...T, ...T, ...T, ...T,
450
417
  * type Ten = Numeric<"10">;
451
418
  * ```
452
419
  */
453
- declare type Numeric<S extends string, T extends any[] = []> = S extends `${infer S1}${infer S2}` ? S1 extends Digital ? Numeric<S2, [...Multiply10<T>, ...MakeArray<S1>]> : never : T["length"];
420
+ type Numeric<S extends string, T extends any[] = []> = S extends `${infer S1}${infer S2}` ? S1 extends Digital ? Numeric<S2, [...Multiply10<T>, ...MakeArray<S1>]> : never : T["length"];
454
421
 
455
422
  /**
456
423
  * **Opaque**
@@ -461,7 +428,7 @@ declare type Numeric<S extends string, T extends any[] = []> = S extends `${infe
461
428
  * Note: taken from [type-fest](https://github.com/sindresorhus/type-fest/blob/main/source/opaque.d.ts)
462
429
  * repo.
463
430
  */
464
- declare type Opaque<Type, Token = unknown> = Type & {
431
+ type Opaque<Type, Token = unknown> = Type & {
465
432
  readonly __opaque__: Token;
466
433
  };
467
434
 
@@ -479,7 +446,7 @@ declare type Opaque<Type, Token = unknown> = Type & {
479
446
  *
480
447
  * **Note:** in essence this is the _opposite_ of `Exclude<T,K>`
481
448
  */
482
- declare type Retain<T, K extends keyof T> = Pick<T, Include<keyof T, K>>;
449
+ type Retain<T, K extends keyof T> = Pick<T, Include<keyof T, K>>;
483
450
 
484
451
  /**
485
452
  * **SameKeys**
@@ -489,7 +456,7 @@ declare type Retain<T, K extends keyof T> = Pick<T, Include<keyof T, K>>;
489
456
  *
490
457
  * Note: meant to be used as part of an _extends_ clause in most cases.
491
458
  */
492
- declare type SameKeys<T extends object, A extends any = any> = {
459
+ type SameKeys<T extends object, A extends any = any> = {
493
460
  [P in keyof T]: A;
494
461
  };
495
462
 
@@ -502,7 +469,7 @@ declare type SameKeys<T extends object, A extends any = any> = {
502
469
  * This type utility assumes that _keys_ of both dictionaries
503
470
  * are the same.
504
471
  */
505
- declare type Transformer<I extends object, O extends SameKeys<I>, K extends keyof I = keyof I> = (input: I, key: K) => O[K];
472
+ type Transformer<I extends object, O extends SameKeys<I>, K extends keyof I = keyof I> = (input: I, key: K) => O[K];
506
473
 
507
474
  /**
508
475
  * **TypeGuard**
@@ -510,7 +477,7 @@ declare type Transformer<I extends object, O extends SameKeys<I>, K extends keyo
510
477
  * a typing for a **TS** type-guard which evaluates an _unknown_ input
511
478
  * and determines if it is of type `T`.
512
479
  */
513
- declare type TypeGuard<T> = (thing: unknown) => thing is T;
480
+ type TypeGuard<T> = (thing: unknown) => thing is T;
514
481
 
515
482
  /**
516
483
  * Allows filtering down `T` to those which extend a given type `U`.
@@ -523,7 +490,7 @@ declare type TypeGuard<T> = (thing: unknown) => thing is T;
523
490
  * type BA = Where<typeof arr, `ba${string}`>;
524
491
  * ```
525
492
  */
526
- declare type Where<T extends Record<string, any> | readonly string[], U> = T extends readonly string[] ? Include<T[number], U> : {
493
+ type Where<T extends Record<string, any> | readonly string[], U> = T extends readonly string[] ? Include<T[number], U> : {
527
494
  [K in keyof T]: K extends U ? K : never;
528
495
  }[keyof T];
529
496
  /**
@@ -537,40 +504,37 @@ declare type Where<T extends Record<string, any> | readonly string[], U> = T ext
537
504
  * type F = WhereNot<typeof arr, `ba${string}`>;
538
505
  * ```
539
506
  */
540
- declare type WhereNot<T extends Record<string, any> | readonly string[], U> = T extends readonly string[] ? Exclude<T[number], U> : {
507
+ type WhereNot<T extends Record<string, any> | readonly string[], U> = T extends readonly string[] ? Exclude<T[number], U> : {
541
508
  [K in keyof T]: K extends U ? never : K;
542
509
  }[keyof T];
543
510
 
544
- declare type AppendToObject<T, U extends keyof any, V> = {
511
+ type AppendToObject<T, U extends keyof any, V> = {
545
512
  [K in keyof T | U]: K extends keyof T ? T[K] : V;
546
513
  };
547
514
  /**
548
515
  * Appends a new Key/Value to an existing dictionary <T>
549
516
  */
550
- declare type AppendToDictionary<TDict, TKey extends string, TValue> = {
517
+ type AppendToDictionary<TDict, TKey extends string, TValue> = {
551
518
  [K in keyof TDict | TKey]: K extends keyof TDict ? TDict[K] : TValue;
552
519
  };
553
520
 
554
521
  /**
555
522
  * Accepts the `true` literal or _undefined_.
556
523
  */
557
- declare type MaybeTrue = true | undefined;
524
+ type MaybeTrue = true | undefined;
558
525
  /**
559
526
  * Accepts the `false` literal or _undefined_.
560
527
  */
561
- declare type MaybeFalse = false | undefined;
562
-
563
- declare type Condition<TInput extends Narrowable, TResult extends boolean> = (input: TInput) => TResult;
564
- declare const condition: <TInput extends Narrowable, C extends Condition<Narrowable, boolean>>(c: C, input: TInput) => boolean;
528
+ type MaybeFalse = false | undefined;
565
529
 
566
530
  /**
567
531
  * A conditional clause used in the application of the `ifTypeOf` utility
568
532
  */
569
- declare type ExtendsClause<N extends Narrowable, TValue extends Record<keyof TValue, N> | number | string | boolean | symbol> = <TBase extends any>(base: TBase) => TValue extends TBase ? true : false;
533
+ type ExtendsClause<N extends Narrowable, TValue extends Record<keyof TValue, N> | number | string | boolean | symbol> = <TBase extends any>(base: TBase) => TValue extends TBase ? true : false;
570
534
  /**
571
535
  * A conditional clause used in the application of the `ifTypeOf` utility
572
536
  */
573
- declare type ExtendsNarrowlyClause<N extends Narrowable, TValue extends Record<keyof TValue, N> | number | string | boolean | symbol> = <NB extends Narrowable, TBase extends Record<keyof TBase, NB> | number | string | boolean | symbol>(base: TBase) => TValue extends TBase ? true : false;
537
+ type ExtendsNarrowlyClause<N extends Narrowable, TValue extends Record<keyof TValue, N> | number | string | boolean | symbol> = <NB extends Narrowable, TBase extends Record<keyof TBase, NB> | number | string | boolean | symbol>(base: TBase) => TValue extends TBase ? true : false;
574
538
  /**
575
539
  * **TypeCondition**
576
540
  *
@@ -580,1126 +544,962 @@ declare type ExtendsNarrowlyClause<N extends Narrowable, TValue extends Record<k
580
544
  * - `extends` - compares with _wide_ types
581
545
  * - `narrowlyExtends` - compares with _narrow_ / _literal_ types
582
546
  */
583
- declare type TypeCondition<N extends Narrowable, TValue extends Record<keyof TValue, N> | number | string | boolean | symbol> = {
547
+ type TypeCondition<N extends Narrowable, TValue extends Record<keyof TValue, N> | number | string | boolean | symbol> = {
584
548
  extends: ExtendsClause<N, TValue>;
585
549
  narrowlyExtends: ExtendsNarrowlyClause<N, TValue>;
586
550
  };
587
- declare const ifTypeOf: <N extends Narrowable, TValue extends string | number | boolean | symbol | Record<keyof TValue, N>>(val: TValue) => TypeCondition<N, TValue>;
588
-
589
- declare type IsArray<T> = T extends any[] ? true : false;
590
- declare function isArray<T>(i: T): IsArray<T>;
591
551
 
592
- declare type IsBoolean<T> = T extends boolean ? true : false;
552
+ type LowerAlpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z";
553
+ /** Uppercase alphabetic character */
554
+ type UpperAlpha = Uppercase<LowerAlpha>;
593
555
  /**
594
- * Runtime and type checks whether a variable is a boolean value.
556
+ * Alphabetical characters (upper and lower)
595
557
  */
596
- declare function isBoolean<T extends any>(i: T): IsBoolean<T>;
558
+ type Alpha = UpperAlpha | LowerAlpha;
559
+ type Whitespace = " " | "\n" | "\t";
560
+ type Punctuation = "." | "," | ";" | "!" | "?";
597
561
  /**
598
- * **ifBoolean**
599
- *
600
- * Strongly type-aware conditional statement which checks whether a value is
601
- * a _boolean_ and returns one of two values (strongly typed) based on the evaluation
602
- * of this criteria.
603
- *
604
- * @param val the value being tested
605
- * @param ifVal the value (strongly typed) returned if val is _boolean_
606
- * @param elseVal the value (strongly typed) returned if val is NOT a _boolean
562
+ * Characters which typically are used to separate words (but not including a space)
607
563
  */
608
- declare function ifBoolean<T, IF, ELSE>(val: T, ifVal: IF, elseVal: ELSE): IsBoolean<T> extends true ? IF : ELSE;
609
-
610
- declare type IsFalse<T extends Narrowable> = IsBoolean<T> extends true ? T extends false ? true : true extends T ? false : unknown : false;
611
- declare function isFalse<T>(i: T): IsFalse<T>;
564
+ type StringDelimiter = "_" | "-" | "/" | "\\";
565
+ type OpeningBracket = "(" | "[" | "{";
566
+ type ClosingBracket = ")" | "]" | "}";
567
+ /**
568
+ * Opening and closing parenthesis
569
+ */
570
+ type Parenthesis = "(" | ")";
571
+ /**
572
+ * Opening and closing brackets
573
+ */
574
+ type Bracket = OpeningBracket | ClosingBracket;
575
+ /**
576
+ * Numeric string characters
577
+ */
578
+ type NumericString = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
579
+ /**
580
+ * Any alphabetic or numeric string character
581
+ */
582
+ type AlphaNumeric = Alpha | NumericString;
583
+ /**
584
+ * Allows alphanumeric characters and some special characters typically allowed
585
+ * in variable names.
586
+ */
587
+ type VariableName = AlphaNumeric | "_" | "." | "-";
588
+ type SpecialCharacters = "@" | "~" | "^" | "#" | "&" | "*";
589
+ /**
590
+ * Non-alphabetic characters including whitespace, string numerals, and
591
+ */
592
+ type NonAlpha = Whitespace | Punctuation | NumericString | Bracket | SpecialCharacters;
593
+ type Ipv4 = `${number}.${number}.${number}.${number}`;
612
594
 
613
- declare type IsFunction<T> = T extends FunctionType ? true : false;
614
595
  /**
615
- * Checks whether a passed in value is a function and ensures run-time and types
616
- * are consistent.
596
+ * Extracts the _required_ keys in the object's type. You also may
597
+ * optionally filter by the _value_ of the key.
598
+ */
599
+ type RequiredKeys<T extends object, V extends any = any> = {
600
+ [K in keyof T]-?: {} extends {
601
+ [P in K]: T[K];
602
+ } ? never : T[K] extends V ? K : never;
603
+ }[keyof T];
604
+ /**
605
+ * Extracts the intersecting/common keys to two objects
606
+ */
607
+ type IntersectingKeys<T extends Record<string, any> | readonly string[], U extends Record<string, any> | readonly string[]> = {
608
+ [K in keyof T]: K extends Keys<U> ? K : never;
609
+ }[keyof T];
610
+ /**
611
+ * Extracts the _optional_ keys in the object's type. You also may
612
+ * optionally filter by the _value_ of the key.
613
+ */
614
+ type OptionalKeys<T extends object, V extends any = any> = {
615
+ [K in keyof T]-?: {} extends {
616
+ [P in K]: T[K];
617
+ } ? V extends T[K] ? K : never : never;
618
+ }[keyof T];
619
+ /**
620
+ * The _keys_ on a given object `T` which have a literal value of `W`.
621
+ *
622
+ * Optionally, you may provide a generic `E` to exclude certain keys in
623
+ * result set.
617
624
  * ```ts
618
- * // true
619
- * const yup = isFunction(() => "hello world");
625
+ * // "foo"
626
+ * type Str = KeysWithValue<{ foo: "hi"; bar: 5 }>;
620
627
  * ```
621
- *
622
- * Note: the runtime `typeof [variable]` will correctly say "function" when a function is
623
- * encountered but if that function also has object types defined then the type will be a big
624
- * and ugly union type. This function will give you a proper boolean value in both cases.
625
628
  */
626
- declare function isFunction<T extends unknown>(input: T): IsFunction<T>;
627
-
628
- declare type IsNull<T> = T extends null ? true : false;
629
- declare function isNull<T extends Narrowable>(i: T): T extends null ? true : false;
629
+ type KeysWithValue<W extends any, T extends object> = {
630
+ [K in keyof T]: T[K] extends W ? Readonly<K> : never;
631
+ }[keyof T];
630
632
  /**
631
- * **ifNull**
632
- *
633
- * Strongly type-aware conditional statement which checks whether a value is
634
- * Null and returns one of two values (strongly typed) based on the evaluation
635
- * of this criteria.
636
- *
637
- * @param val the value being tested
638
- * @param ifVal the value (strongly typed) returned if val is `null`
639
- * @param elseVal the value (strongly typed) returned if val is NOT `null`
633
+ * A `PrivateKey` must start with a `_` character and then follow with
634
+ * an alphabetic character
640
635
  */
641
- declare function ifNull<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IsNull<T> extends true ? IF : ELSE;
642
-
643
- declare type IsNumber<T> = T extends number ? true : false;
644
- declare function isNumber<T>(i: T): T extends number ? true : false;
636
+ type PrivateKey = `_${Alpha}${string}`;
645
637
  /**
646
- * **ifNumber**
647
- *
648
- * Strongly type-aware conditional statement which checks whether a value is
649
- * a _number_ and returns one of two values (strongly typed) based on the evaluation
650
- * of this criteria.
638
+ * Keys on an object which have a `_` character as first part of the
639
+ * name are considered private and this utility will create a union
640
+ * of all the keys in this category.
641
+ */
642
+ type PrivateKeys<T extends object> = {
643
+ [K in keyof T]: K extends `_${string}` ? K : never;
644
+ }[keyof T];
645
+ /**
646
+ * **PublicKeys**
651
647
  *
652
- * @param val the value being tested
653
- * @param ifVal the value (strongly typed) returned if val is number
654
- * @param elseVal the value (strongly typed) returned if val is NOT a number
648
+ * Builds a union type of all keys which are "public" where a public
649
+ * key is any key which _does not_ start with the `_` character.
655
650
  */
656
- declare function ifNumber<T, IF, ELSE>(val: T, ifVal: IF, elseVal: ELSE): IsNumber<T> extends true ? IF : ELSE;
657
-
658
- declare type ObjectType = Not<Record<string, Narrowable>, FunctionType>;
651
+ type PublicKeys<T extends object> = {
652
+ [K in keyof T]: K extends `_${string}` ? never : K;
653
+ }[keyof T];
654
+ type StringKeys<T extends object> = {
655
+ [K in keyof T]: K extends string ? Readonly<K> : never;
656
+ }[keyof T];
659
657
  /**
660
- * Detects whether the passed in `v` is of type "object" where an object
661
- * is defined to be a string keyed dictionary style object. This means that
662
- * arrays are excluded, as well as functions which also have properties hanging
663
- * off of them.
658
+ * The keys of an object which _are not_ a string type
664
659
  */
665
- declare function isObject<T extends unknown>(i: T): IsObject<T>;
666
-
667
- declare type IsString<T> = T extends string ? true : false;
668
- declare function isString<T>(i: T): IsString<T>;
660
+ type NonStringKeys<T extends object> = {
661
+ [K in keyof T]: K extends string ? never : Readonly<K>;
662
+ }[keyof T];
663
+ type NumericKeys<T extends object> = {
664
+ [K in keyof T]: K extends number ? Readonly<K> : never;
665
+ }[keyof T];
666
+ type NonNumericKeys<T extends object> = {
667
+ [K in keyof T]: K extends number ? never : Readonly<K>;
668
+ }[keyof T];
669
669
  /**
670
- * **ifString**
670
+ * **RequiredProps**
671
671
  *
672
- * Strongly type-aware conditional statement which checks whether a value is
673
- * a _string_ and returns one of two values (strongly typed) based on the evaluation
674
- * of this criteria.
672
+ * Reduces an object type to only key/value pairs where the key is required
673
+ */
674
+ type RequiredProps<T extends object> = Pick<T, RequiredKeys<T>>;
675
+ /**
676
+ * **OptionalProps**
675
677
  *
676
- * @param val the value being tested
677
- * @param ifVal the value (strongly typed) returned if val is _string_
678
- * @param elseVal the value (strongly typed) returned if val is NOT a _string
678
+ * Reduces an object to only key/value pairs where the key is optional
679
679
  */
680
- declare function ifString<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IsString<T> extends true ? IF : ELSE;
681
-
682
- declare function isSymbol<T>(i: T): T extends symbol ? true : false;
683
-
680
+ type OptionalProps<T extends object> = Pick<T, OptionalKeys<T>>;
684
681
  /**
685
- * Type utility which returns `true` or `false` based on
686
- * whether the type holds the narrow "true" type.
682
+ * **WithValue**
683
+ *
684
+ * Reduces an object's type down to only those key/value pairs where the
685
+ * value is of type `W`.
687
686
  * ```ts
688
- * // true
689
- * type T = IsTrue<true>;
690
- * // unknown
691
- * type U = IsTrue<boolean>;
692
- * // false
693
- * type F = IsTrue<false>;
694
- * type F2 = IsTrue<"false">;
687
+ * const foo = { a: 1, b: "hi", c: () => "hello" }
688
+ * // { c: () => "hello" }
689
+ * type W = WithValue<Function, typeof foo>
695
690
  * ```
696
691
  */
697
- declare type IsTrue<T> = IsBoolean<T> extends true ? T extends true ? true : T extends false ? false : unknown : false;
692
+ type WithValue<W extends any, T extends object, E extends any = undefined> = undefined extends E ? Pick<T, KeysWithValue<W, T>> : Omit<Pick<T, KeysWithValue<W, T>>, KeysWithValue<E, T>>;
698
693
  /**
699
- * Run-time and type checking of whether a variable is `true`.
694
+ * Reduces an object to only the key/value pairs where the key is a
695
+ * string.
700
696
  */
701
- declare function isTrue<T extends Narrowable>(i: T): IsTrue<T>;
697
+ type WithStringKeys<T extends object> = Omit<T, NonStringKeys<T>>;
702
698
  /**
703
- * **ifTrue**
704
- *
705
- * Strongly type-aware conditional statement which checks whether a value is
706
- * a _true_ and returns one of two values (strongly typed) based on the evaluation
707
- * of this criteria.
708
- *
709
- * @param val the value being tested
710
- * @param ifVal the value (strongly typed) returned if val is _true_ value
711
- * @param elseVal the value (strongly typed) returned if val is NOT a _true_ value
699
+ * Reduces an object to only the key/value pairs where the key is numeric.
712
700
  */
713
- declare function ifTrue<T, IF, ELSE>(val: T, ifVal: IF, elseVal: ELSE): IsTrue<T> extends true ? IF : ELSE;
701
+ type WithNumericKeys<T extends object> = Omit<T, NonNumericKeys<T>>;
714
702
 
715
- declare function isUndefined<T extends Narrowable>(i: T): undefined extends T ? true : false;
716
703
  /**
717
- * **ifUndefined**
718
- *
719
- * Strongly type-aware conditional statement which checks whether a value is
720
- * _undefined_ and returns one of two values (strongly typed) based on the evaluation
721
- * of this criteria.
704
+ * **RuleDefinition**
722
705
  *
723
- * @param val the value being tested
724
- * @param ifVal the value (strongly typed) returned if val is `undefined`
725
- * @param elseVal the value (strongly typed) returned if val is NOT `undefined`
706
+ * A rule definition is the typing for the fluent API surface that is built up
707
+ * with the **ruleset** utility.
726
708
  */
727
- declare function ifUndefined<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IsUndefined<T> extends true ? IF : ELSE;
728
-
729
- declare type Type<T extends any, V extends Function> = {
730
- name: string;
731
- type: T;
732
- typeGuard: TypeGuard<T>;
733
- is: V;
734
- };
735
- declare const typeApi: () => {
736
- readonly string: Type<string, typeof isString>;
737
- readonly boolean: Type<boolean, typeof isBoolean>;
738
- readonly number: Type<number, typeof isNumber>;
739
- readonly function: Type<Function | (Function & {
740
- [key: string]: any;
741
- }), typeof isFunction>;
742
- readonly null: Type<null, typeof isNull>;
743
- readonly symbol: Type<symbol, typeof isSymbol>;
744
- readonly undefined: Type<undefined, typeof isUndefined>;
745
- readonly true: Type<true, typeof isTrue>;
746
- readonly false: Type<false, typeof isFalse>;
747
- readonly object: Type<Record<string, Narrowable>, typeof isObject>;
748
- readonly array: Type<any[], typeof isArray>;
709
+ type RuleDefinition<
710
+ /** the data which will be evaluated on rule execution */
711
+ T extends object,
712
+ /** the optional props -- as a union type -- which must be defined per the rule */
713
+ H extends string = "",
714
+ /** the key/values which will be evaluated on execution (wide type) */
715
+ E extends Partial<SameKeys<T>> = {},
716
+ /** the key/values which will be evaluated on execution (narrow type) */
717
+ N extends Partial<SameKeys<T>> = {}> = {
718
+ /**
719
+ * sets up a true/false check that a given property is defined; this
720
+ * condition can only be applied to _optional_ properties.
721
+ */
722
+ has(optProp: OptionalKeys<T>): RuleDefinition<T, H & typeof optProp, E, N>;
723
+ /**
724
+ * Validates that a given property extends a certain value's type; comparison
725
+ * is made assuming "wide types".
726
+ */
727
+ equals<K extends keyof T, V extends Pick<T, K>>(prop: K, value: V): RuleDefinition<T, H, E & Record<K, V>, N>;
728
+ /**
729
+ * Validates that a given property extends a certain value's type; comparison
730
+ * is made assuming "narrow types". This is only available for props which
731
+ * expose a
732
+ */
733
+ narrowlyEquals<K extends keyof T, V extends Pick<T, K>>(prop: K, value: V): RuleDefinition<T, H, E, N & Record<K, V>>;
749
734
  };
750
- declare type TypeApi = ReturnType<typeof typeApi>;
751
- declare function isType<T extends any, V extends Function>(t: unknown): t is Type<T, V>;
752
- declare type TypeDefinition<T extends any, V extends Function> = (defn: TypeApi) => Type<T, V>;
753
- declare function type<T extends any, V extends Function>(fn: TypeDefinition<T, V>): Type<T, V>;
735
+ /**
736
+ * **DynamicRule**
737
+ *
738
+ * A dynamic rule allows type and runtime validation of a data structure
739
+ * which extends a known `State`. It then returns the literal type `true`
740
+ * or `false`.
741
+ *
742
+ * ```ts
743
+ * type State = { id?: string; favorite: boolean; color: string };
744
+ * // type-safe way to check whether optional prop is actually set
745
+ * const rule: DynamicRule<State> = s => s
746
+ * .has("id")
747
+ * .equals("favorite", true)
748
+ * .equals("color", "red");
749
+ * ```
750
+ */
751
+ type DynamicRule<TState extends any, TResult extends true | false> = (rule: TypeCondition<any, TState>) => TResult;
752
+ /**
753
+ * **DynamicRuleSet**
754
+ *
755
+ * A function which accepts the agreed `TState` generic as input and returns a discrete
756
+ * `true` or `false` value.
757
+ */
758
+ type DynamicRuleSet<TState extends any, TRules extends Record<string, TypeCondition<any, TState>>> = (rules: TRules) => true | false;
759
+
760
+ type RuntimeType<T> = {
761
+ __kind: "type";
762
+ type: T;
763
+ is: TypeGuard<T>;
764
+ };
765
+ type RuntimeProp<P extends Readonly<PropertyKey>, T extends RuntimeType<any>> = {
766
+ __kind: "prop";
767
+ key: Readonly<P>;
768
+ valueType: Readonly<T["type"]>;
769
+ /**
770
+ * Provides the _type_ to the type system when used with `typeof`.
771
+ *
772
+ * ```ts
773
+ * const t = number();
774
+ * // number
775
+ * type T = typeof t.type;
776
+ * ```
777
+ *
778
+ * **Note:** _the runtime system will get a string equivalent name:_
779
+ * ```ts
780
+ * const t = number();
781
+ * // "number"
782
+ * console.log(t.type);
783
+ * ```
784
+ */
785
+ type: Record<P, T["type"]>;
786
+ is: TypeGuard<Record<P, T["type"]>>;
787
+ };
788
+ type TypeOptions<T extends Partial<object> = {}> = {
789
+ /** each type has a default type guard but you can override if you need to be more specific */
790
+ typeGuard?: TypeGuard<T>;
791
+ } & T;
754
792
 
755
793
  /**
756
- * Given a dictionary of key/values, where the value is a function, this
757
- * type utility will maintain the keys but change the values to whatever
758
- * the `ReturnType` of the function was.
794
+ * Validates that a given type extends another and returns `true` or `false` type
795
+ */
796
+ type ExpectExtends<VALUE, EXPECTED> = EXPECTED extends VALUE ? true : false;
797
+ /**
798
+ * Validates that a given type extends another and returns `any` or `never` as a type
799
+ */
800
+ type AssertExtends<VALUE, EXPECTED> = EXPECTED extends VALUE ? any : never;
801
+ /**
802
+ * Give a type `TValue` and a comparison type `TExtends`
803
+ */
804
+ type IfExtendsThen<VALUE, EXPECTED, THEN> = EXPECTED extends VALUE ? THEN : never;
805
+
806
+ /**
807
+ * Indicates whether `T` has _all_ uppercase characters in it.
759
808
  * ```ts
760
- * const api = {
761
- * val: 42,
762
- * hi: (name: string) => `hi ${name}`,
763
- * bye: (name: string) => `bye ${name}`
764
- * };
765
- * // { hi: string; bye: string }
766
- * type Test = UnwrapValue<typeof api>
767
- * // { val: number; foo: string; bar: string }
768
- * type Test2 = UnwrapValue<typeof api, false>
809
+ * // true
810
+ * type T = AllCaps<"FOOBAR">;
811
+ * // false
812
+ * type T = AllCaps<"FooBar">;
813
+ * // "unknown"
814
+ * type T = AllCaps<string>;
769
815
  * ```
770
816
  */
771
- declare type DictPartialApplication<T extends Record<string, any>, I extends boolean = true> = SimplifyObject<{
772
- [K in keyof T]: T[K] extends (...args: any[]) => any ? Record<K, ReturnType<T[K]>> : true extends I ? never : Record<K, T[K]>;
773
- }[keyof T]>;
817
+ type AllCaps<T extends string> = string extends T ? "unknown" : T extends Uppercase<T> ? true : false;
774
818
 
775
819
  /**
776
- * Allow a dictionary have it's value's type changed to `T` while maintaining the keys in
777
- * the original object `I` so long as the original value for the KV pair extends `V`.
778
- *
779
- * If `V` is not specified then it defaults to _any_ and therefore all KVs are preserved.
820
+ * **Break<T,D>**
780
821
  *
822
+ * Takes a string `T`, and splits it into a tuple of the form `[F, R]`.
781
823
  * ```ts
782
- * type Obj = { foo: "hello", bar: 42, baz: () => "world" };
783
- * // { foo: number, bar: number, baz: number };
784
- * type AllNumbers = DictChangeValue<Obj, number>;
785
- * // { foo: number }
786
- * type StringToBool = DictChangeValue<Obj, boolean, string>
824
+ * // ["the", " long and winding road"]
825
+ * type T1 = Break<"the long and winding road", " ">;
826
+ * // ["there", " I was, there I was"]
827
+ * type T2 = Break<"there I was, there I was", " ">;
787
828
  * ```
788
829
  */
789
- declare type DictChangeValue<
790
- /** the object who's value-type we're changing */
791
- I extends Record<string, any>,
792
- /** the return type that functions should be modified to have */
793
- T extends any,
830
+ type Break<T extends string, D extends string> = (string extends T ? [string, string] : (T extends `${infer F}${D}${infer _R}` ? (F extends `${infer _X}${D}${infer _Y}` ? never : (T extends `${F}${infer R}` ? [F, R] : never)) : [T, ""]));
831
+
794
832
  /**
795
- *The type we expect in the value; if the value extends type `V` then the value will
796
- * be converted to type `O`; if not then the KV pair will be discarded
833
+ * Concatenates two arrays (of literals).
834
+ * ```ts
835
+ * // [ "foo", "bar", "baz" ]
836
+ * type T = ArrConcat<["foo"], ["bar", "baz"]>;
837
+ * ```
797
838
  */
798
- V extends any = any> = SimplifyObject<{
799
- [K in keyof I]: I[K] extends V ? Record<K, T> : never;
800
- }[keyof I]>;
839
+ type ArrConcat<A extends any[], B extends any[]> = [...A, ...B];
801
840
 
802
841
  /**
803
- * **DictPrependWithFn**
804
- *
805
- * Given a strongly typed object `<T>`, this utility will inject a function call with
806
- * arguments `<A>` and then return what had subsequently been the value of the property.
842
+ * Type utility which takes a string `S` and replaces the substring `W` with `P`.
843
+ * ```ts
844
+ * const fooy = "fooy";
845
+ * // "Foo"
846
+ * type Foo = Replace<typeof fooy, "y", "">;
847
+ * ```
807
848
  *
808
- * Should you only want to apply this treatment to _some_ of the properties you can
809
- * pass in a value `<E>` which will ensure that only properties which _extend_ `E` will be
810
- * modified.
849
+ * Note: _the first match is replaced and all subsequent matches are ignored_
811
850
  */
812
- declare type DictPrependWithFn<T extends Record<string, any>, A extends any[], E extends any = any> = SimplifyObject<{
813
- [K in keyof T]: T[K] extends E ? Record<K, (...args: A) => T[K]> : Record<K, T[K]>;
814
- }[keyof T]>;
851
+ type Replace<S extends string, W extends string, P extends string> = S extends "" ? "" : W extends "" ? S : S extends `${infer F}${W}${infer E}` ? `${F}${P}${E}` : S;
815
852
 
816
853
  /**
817
- * **DictReturnValues**
818
- *
819
- * A type utility which receives an object `<T>` and then modifies
820
- * the return type of any properties which are a function to have this
821
- * new **ReturnType** `<R>`. Optionally you can specify a particular return type which
822
- * you are targeting and then
854
+ * Trims off whitespace on left of string
855
+ * ```ts
856
+ * // "foobar "
857
+ * type T = TrimLeft<"\n\t foobar ">;
858
+ * // string
859
+ * type T = TrimLeft<string>;
860
+ * ```
823
861
  */
824
- declare type DictReturnValues<
825
- /** the object which we expect to have props with function values */
826
- T extends Record<string, any>,
827
- /** the return type that functions should be modified to have */
828
- R extends any,
829
- /** optionally this utility can target only functions with a certain existing return value */
830
- O extends (...args: any[]) => any = (...args: any[]) => any> = SimplifyObject<{
831
- [K in keyof T]: T[K] extends O ? T[K] extends (...args: infer A) => any ? Record<K, (...args: A) => R> : Record<K, T[K]> : Record<K, T[K]>;
832
- }[keyof T]>;
862
+ type TrimLeft<S extends string> = string extends S ? string : S extends `${Whitespace}${infer Right}` ? TrimLeft<Right> : S;
833
863
 
834
864
  /**
835
- * Get the type of a property of an object:
865
+ * Provides the _left_ whitespace of a string
836
866
  * ```ts
837
- * const car = { make: "Chevy", model: "Malibu", }
867
+ * // "\n\t "
868
+ * type T = LeftWhitespace<"\n\t foobar">;
838
869
  * ```
839
870
  */
840
- declare type Get<T, K> = K extends `${infer FK}.${infer L}` ? FK extends keyof T ? Get<T[FK], L> : never : K extends keyof T ? T[K] : never;
871
+ type LeftWhitespace<S extends string> = string extends S ? string : Replace<S, TrimLeft<S>, "">;
841
872
 
842
873
  /**
843
- * Expresses whether an option is "opt" (optional) or "req" (required)
874
+ * Trims off whitespace on left of string
875
+ * ```ts
876
+ * // "\n foobar"
877
+ * type T = TrimRight<"\n foobar \t">;
878
+ * // string
879
+ * type T = TrimRight<string>;
880
+ * ```
844
881
  */
845
- declare type OptRequired = "opt" | "req";
882
+ type TrimRight<S extends string> = string extends S ? string : S extends `${infer Right}${Whitespace}` ? TrimRight<Right> : S;
846
883
 
847
- declare const DEFAULT_ONE_TO_MANY_MAPPING: FinalizedMapConfig<"req", "I -> O[]", "opt">;
848
- declare const DEFAULT_ONE_TO_ONE_MAPPING: FinalizedMapConfig<"req", "I -> O", "req">;
849
- declare const DEFAULT_MANY_TO_ONE_MAPPING: FinalizedMapConfig<"req", "I[] -> O", "req">;
850
- declare type DefaultOneToManyMapping = typeof DEFAULT_ONE_TO_MANY_MAPPING;
851
- declare type DefaultOneToOneMapping = typeof DEFAULT_ONE_TO_ONE_MAPPING;
852
- declare type DefaultManyToOneMapping = typeof DEFAULT_MANY_TO_ONE_MAPPING;
853
884
  /**
854
- * **mapTo** _utility_
855
- *
856
- * This utility -- by default -- creates a strongly typed 1:M data mapper which maps from one
857
- * known source `I` to any array of another `O[]`:
885
+ * Provides the _left_ whitespace of a string
858
886
  * ```ts
859
- * const mapper = mapTo<I, O>(i => [{
860
- * foo: i.bar
861
- * }]);
887
+ * // "\n\t "
888
+ * type T = LeftWhitespace<"\n\t foobar">;
862
889
  * ```
863
890
  */
864
- declare const mapToFn: ConfiguredMap<DefaultOneToManyMapping>["map"];
891
+ type RightWhitespace<S extends string> = string extends S ? string : Replace<S, TrimRight<S>, "">;
892
+
865
893
  /**
866
- * Provides a `config` method which allows the relationships between _inputs_
867
- * and _outputs_ to be configured.
894
+ * Type utility that provides the _length_ of a given string type in a way which
895
+ * is _not_ limited to TS's recursive string length of roughly 48.
896
+ *
897
+ * ```ts
898
+ * // 3
899
+ * type Three = StringLength<"foo">;
900
+ * ```
868
901
  */
869
- declare const mapToDict: MapperApi;
902
+ type StringLength<S extends string, R extends number[] = []> = S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer _Sevebnth}${infer _Eighth}${infer _Ninth}${infer _Tenth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer _Sevebnth}${infer _Eighth}${infer _Ninth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer _Sevebnth}${infer _Eighth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer _Sevebnth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer Rest}` ? StringLength<Rest, [...R, 1, 1]> : S extends `${infer _First}${infer Rest}` ? StringLength<Rest, [...R, 1]> : [...R]["length"];
903
+
870
904
  /**
871
- * **mapTo** _utility_
872
- *
873
- * This utility creates a strongly typed data mapper which maps from one
874
- * known source `I` to another `O`.
875
- *
876
- * Signatures:
905
+ * Trims off blank spaces, `\n` and `\t` characters from both sides of a _string literal_.
877
906
  * ```ts
878
- * const defMap = mapTo<I,O>( ... );
879
- * const configured = mapTo.config({ output: "req" }).map<I,O>( ... );
880
- * const one2one = mapTo.oneToOne().map<I,O>( ... );
881
- * const many2one = mapTo.manyToOne().map<I,O>( ... );
907
+ * // "foobar"
908
+ * type T = Trim<"\n\t foobar ">;
909
+ * // string
910
+ * type T = Trim<string>;
882
911
  * ```
883
912
  */
884
- declare const mapTo: (<I, O>(map: (source: I) => O[]) => Mapper<I, O, FinalizedMapConfig<"req", "I -> O[]", "opt">>) & MapperApi;
913
+ type Trim<S extends string> = string extends S ? string : S extends `${Whitespace}${infer Right}` ? Trim<Right> : S extends `${infer Left}${Whitespace}` ? Trim<Left> : S;
885
914
 
886
915
  /**
887
- * Expresses relationship between inputs/outputs:
916
+ * An email address
888
917
  */
889
- declare enum MapCardinality {
890
- /** every input results in 0:M outputs */
891
- OneToMany = "I -> O[]",
892
- /** every input results in 0:1 outputs */
893
- OneToOne = "I -> O",
894
- /** every input is an array of type I and reduced to a single O */
895
- ManyToOne = "I[] -> O"
896
- }
897
- declare type MapCardinalityIllustrated = EnumValues<MapCardinality>;
918
+ type Email = `${string}@${string}.${string}`;
919
+ type Zip5 = `${NumericString}${NumericString}${string}${NumericString}`;
920
+ type Zip4 = `${NumericString}${string}`;
898
921
  /**
899
- * The _user_ configuration of a **mapTo** mapper function
900
- * which will be finalized by merging it with the appropriate
901
- * default mapping type.
922
+ * A relatively strong type for Zip5 or Zip5+4 zip codes
902
923
  */
903
- interface MapConfig<IR extends OptRequired | undefined = undefined, D extends MapCardinalityIllustrated | undefined = undefined, OR extends OptRequired | undefined = undefined> {
904
- input?: IR;
905
- output?: OR;
906
- cardinality?: D;
907
- /**
908
- * Whether calls to the final `MapFn` will be logged to stderr
909
- * for debugging purposes. Defaults to false; if you specify
910
- * a _string_ for a value that will be sent to stderr along
911
- * with other debugging info.
912
- */
913
- debug?: boolean | string;
914
- }
924
+ type ZipCode = Zip5 | `${Zip5}-${Zip4}`;
925
+
915
926
  /**
916
- * A finalized configuration of a **mapTo** mapper functions cardinality
917
- * relationships between _inputs_ and _outputs_.
918
- *
919
- * Note: _this configuration does _not_ yet include the actual mapping
920
- * configuration between the input and output._
921
- */
922
- declare type FinalizedMapConfig<IR extends OptRequired = MapIR<DefaultOneToManyMapping>, D extends MapCardinalityIllustrated = MapCard<DefaultOneToManyMapping>, OR extends OptRequired = MapOR<DefaultOneToManyMapping>> = Required<Omit<MapConfig<IR, D, OR>, "debug">> & {
923
- finalized: true;
924
- debug: boolean | string;
925
- };
927
+ * If **ALL CAPS** it converts to all lowercase; if not then it does nothing */
928
+ type LowerAllCaps<T extends string> = AllCaps<T> extends true ? Lowercase<T> : T;
929
+
930
+ type Delimiter = "_" | "-" | " ";
931
+ /** convert all delimiters to dashes */
932
+ type DashDelim<T extends string> = T extends `${infer Begin}${" "}${infer Rest}` ? DashDelim<`${Begin}-${Rest}`> : T extends `${infer Begin}${"_"}${infer Rest}` ? DashDelim<`${Begin}-${Rest}`> : T;
926
933
  /**
927
- * User configuration exposed by a config function which specifies the
928
- * cardinality already (e.g., `oneToMany()`, `manyToOne()`)
934
+ * Converts a string literal type to a **PascalCase** representation.
935
+ * ```ts
936
+ * // "FooBar"
937
+ * type T = PascalCase<"fooBar">;
938
+ * type T = PascalCase<"foo-bar">;
939
+ * type T = PascalCase<"foo_bar">;
940
+ * type T = PascalCase<"\n foo_bar \t">;
941
+ * ```
929
942
  */
930
- declare type MapCardinalityConfig<IR extends OptRequired | undefined, OR extends OptRequired | undefined> = {
931
- /** whether we the input can _optionally_ be an `undefined` value or not */
932
- input?: IR;
933
- /** whether we the output can _optionally_ be an `undefined` value or not */
934
- output?: OR;
935
- /**
936
- * Whether calls to the final `MapFn` will be logged to stderr
937
- * for debugging purposes. Defaults to false; if you set to a string
938
- * value than this will be echoed out with stderr.
939
- */
940
- debug?: boolean | string;
941
- };
943
+ type PascalCase<S extends string> = string extends S ? string : Trim<DashDelim<LowerAllCaps<S>>> extends `${infer Begin}${Delimiter}${infer Rest}` ? PascalCase<`${Capitalize<Begin>}${Capitalize<Rest>}`> : Capitalize<Trim<LowerAllCaps<S>>>;
944
+
945
+ type CamelCase<S extends string> = string extends S ? string : Uncapitalize<PascalCase<S>>;
946
+
942
947
  /**
943
- * **ConfiguredMap**
944
- *
945
- * A partial application of the mapTo() utility which has expressed the
946
- * configuration of the _inputs_ and _outputs_ and provides a `.map()`
947
- * method which allows the user configure the specifics of the mapping.
948
+ * Capitalize all words in a string
948
949
  */
949
- declare type ConfiguredMap<C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = {
950
- map: <I, O>(map: MapTo<I, O, C>) => Mapper<I, O, C>;
951
- input: MapIR<C>;
952
- cardinality: MapCard<C>;
953
- output: MapOR<C>;
954
- debug: boolean | string;
955
- };
950
+ type CapitalizeWords<S extends string> = S extends `${infer L} ${infer R}` ? `${CapitalizeWords<L>} ${CapitalizeWords<R>}` : S extends `${infer L},${infer R}` ? `${CapitalizeWords<L>},${CapitalizeWords<R>}` : S extends `${infer L}.${infer R}` ? `${CapitalizeWords<L>}.${CapitalizeWords<R>}` : Capitalize<S>;
951
+
952
+ type DashToSnake<T extends string> = T extends `${infer HEAD}-${infer TAIL}` ? DashToSnake<`${HEAD}_${TAIL}`> : T;
953
+
956
954
  /**
957
- * Extracts the IR, Cardinality, and OR generics from a FinalizedMapConfig
955
+ * Indicates whether `T` has uppercase characters in it.
956
+ * ```ts
957
+ * // true
958
+ * type T = HasUppercase<"Foobar">;
959
+ * // false
960
+ * type T = HasUppercase<"foobar">;
961
+ * // "unknown"
962
+ * type T = HasUppercase<string>;
963
+ * ```
958
964
  */
959
- declare type DecomposeMapConfig<M extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = M extends MapConfig<infer IR, infer D, infer OR> ? IR extends OptRequired | undefined ? D extends MapCardinalityIllustrated | undefined ? OR extends OptRequired | undefined ? [IR, D, OR] : never : never : never : M extends FinalizedMapConfig<infer IR, infer D, infer OR> ? IR extends OptRequired ? D extends MapCardinalityIllustrated ? OR extends OptRequired ? [IR, D, OR] : never : never : never : never;
960
- /** extracts IR from a `FinalizedMapConfig` */
961
- declare type MapIR<T extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = DecomposeMapConfig<T>[0];
965
+ type HasUppercase<T extends string> = string extends T ? "unknown" : T extends `${string}${UpperAlpha}${string}` ? true : false;
966
+
967
+ type _DU<T extends string> = T extends Lowercase<T> ? T : `-${Lowercase<T>}`;
962
968
  /**
963
- * extracts the MapCardinality from a `FinalizedMapConfig`
969
+ * Converts uppercase characters to a dash and then the lowercase equivalent
970
+ * ```ts
971
+ * // "one-two-three"
972
+ * type T = DashUppercase<"oneTwoThree">;
973
+ * ```
974
+ *
975
+ * _Intended to be used as a lower level utility; prefer `Dasherize<T>` for more full-fledged
976
+ * dash solution_.
964
977
  */
965
- declare type MapCard<T extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = DecomposeMapConfig<T>[1];
966
- /** extracts OR from a `FinalizedMapConfig` */
967
- declare type MapOR<T extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = DecomposeMapConfig<T>[2];
978
+ type DashUppercase<T extends string> = HasUppercase<T> extends false ? T : T extends `${infer C0}${infer C1}${infer R}` ? `${_DU<C0>}${_DU<C1>}${DashUppercase<R>}` : T extends `${infer C0}${infer R}` ? `${_DU<C0>}${DashUppercase<R>}` : "";
979
+
980
+ type OneToOne = `1:1`;
981
+ type OneToMany = `1:M`;
982
+ type OneToZero = `1:0`;
983
+ type ZeroToOne = `0:1`;
984
+ type ZeroToMany = `0:M`;
985
+ type ZeroToZero = `0:0`;
986
+ type ManyToMany = "M:M";
987
+ type ManyToOne = "M:1";
988
+ type ManyToZero = "M:0";
989
+ type CardinalityNode = "0" | "1" | "M";
968
990
  /**
969
- * Merges the types of a userland configuration with a default configuration
991
+ * Cardinality which expects a singular input and requires
992
+ * 1 or many outputs.
993
+ *
994
+ * Note: choose `CardinalityFilter1` if you want to allow output
995
+ * to have no outputs.
970
996
  */
971
- declare type AsFinalizedConfig<U extends MapConfig<OptRequired | undefined, MapCardinalityIllustrated | undefined, OptRequired | undefined>, D extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = TypeDefault<U, D> extends FinalizedMapConfig<infer IR, infer C, infer OR> ? FinalizedMapConfig<IR, C, OR> : never;
972
- declare type MapperApi = {
973
- /**
974
- * Provides opportunity to configure _input_, _output_, and _cardinality_
975
- * prior to providing a mapping function.
976
- *
977
- * Note: _the defaults for configuration are defined by the_ `DEFAULT_ONE_TO_MANY_MAPPING`
978
- * _constant made available as a symbol from this library._
979
- */
980
- config: <C extends MapConfig<OptRequired, //
981
- MapCardinalityIllustrated, OptRequired>>(config: C) => ConfiguredMap<AsFinalizedConfig<C, //
982
- DefaultOneToManyMapping>>;
983
- /**
984
- * Provides a nice 1:1 ratio between the input and output.
985
- *
986
- * By default the input and output are considered to be _required_
987
- * properties but this can be changed with the options hash provided.
988
- * ```ts
989
- * const mapper = mapTo.oneToOne().map(...);
990
- * // add in ability to filter out some inputs
991
- * const mapAndFilter = mapTo.oneToOne({ output: "opt" })
992
- * ```
993
- */
994
- oneToOne: <C extends MapCardinalityConfig<OptRequired, OptRequired>>(config?: C) => ConfiguredMap<AsFinalizedConfig<C, //
995
- DefaultOneToOneMapping>>;
996
- /**
997
- * **manyToOne** _mapping_
998
- *
999
- * Provides a configuration where multiple inputs `I[]` will be mapped to a
1000
- * single output `O`.
1001
- *
1002
- * Choosing this configuration will, by default, set both input and output
1003
- * to be "required" but you can change this default if you so choose.
1004
- */
1005
- manyToOne: <C extends MapCardinalityConfig<OptRequired | undefined, //
1006
- //
1007
- OptRequired | undefined>>(config?: C) => ConfiguredMap<AsFinalizedConfig<C, //
1008
- DefaultManyToOneMapping>>;
1009
- oneToMany: <C extends MapCardinalityConfig<OptRequired | undefined, //
1010
- //
1011
- OptRequired | undefined>>(config?: C) => ConfiguredMap<AsFinalizedConfig<C, //
1012
- DefaultOneToManyMapping>>;
1013
- };
1014
- declare type MapInput<I, //
1015
- IR extends OptRequired, C extends MapCardinalityIllustrated> = C extends MapCardinality.OneToMany | "I -> O[]" ? IR extends "opt" ? I | undefined : I : C extends MapCardinality.OneToOne | "I -> O" ? IR extends "opt" ? I | undefined : I : C extends MapCardinality.ManyToOne | "I[] -> O" ? IR extends "opt" ? I[] | undefined : I[] : never;
1016
- declare type MapOutput<O, //
1017
- OR extends OptRequired, C extends MapCardinalityIllustrated> = C extends MapCardinality.OneToMany | "I -> O[]" ? OR extends "opt" ? O[] : [O, ...O[]] : C extends MapCardinality.OneToOne | "I -> O" ? OR extends "opt" ? O | null : O : C extends MapCardinality.ManyToOne | "I[] -> O" ? OR extends "opt" ? O | null : O : never;
997
+ type Cardinality1 = OneToOne | OneToMany;
1018
998
  /**
1019
- * **MapTo<I, O>**
1020
- *
1021
- * A mapping function between an input type `I` and output type `O`. Defaults to using
1022
- * the _default_ OneToMany mapping config.
1023
- *
1024
- * **Note:** this type is designed to guide the userland mapping; refer
1025
- * to `MapFn` if you want the type output by the `mapFn()` utility.
999
+ * Cardinality which expects a singular input and maps to 0,
1000
+ * 1, or many outputs.
1026
1001
  */
1027
- declare type MapTo<I, O, C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired> = DefaultOneToManyMapping> = MapIR<C> extends "opt" ? (source?: MapInput<I, MapIR<C>, MapCard<C>>) => MapOutput<O, MapOR<C>, MapCard<C>> : (source: MapInput<I, MapIR<C>, MapCard<C>>) => MapOutput<O, MapOR<C>, MapCard<C>>;
1028
- declare type MapFnOutput<I, O, S, OR extends OptRequired, C extends MapCardinalityIllustrated> = C extends "I -> O[]" | MapCardinality.OneToMany ? S extends I[] ? OR extends "opt" ? O[] : [O, ...O[]] : OR extends "opt" ? O[] | null : O[] : C extends MapCardinality.OneToOne | "I -> O" ? S extends I[] ? OR extends "opt" ? O[] : [O, ...O[]] : OR extends "opt" ? O | null : O : C extends MapCardinality.ManyToOne | "I[] -> O" ? S extends I[][] ? OR extends "opt" ? O[] : [O, ...O[]] : OR extends "opt" ? O | null : O : never;
1029
- declare type MapFnInput<I, IR extends OptRequired, D extends MapCardinalityIllustrated> = D extends "I -> O[]" | MapCardinality.OneToMany ? IR extends "opt" ? I | I[] | undefined : I | I[] : D extends MapCardinality.OneToOne | "I -> O" ? IR extends "opt" ? I | I[] | undefined : I | I[] : D extends MapCardinality.ManyToOne | "I[] -> O" ? IR extends "opt" ? I[] | I[][] | undefined : I[] | I[][] : never;
1002
+ type CardinalityFilter1 = OneToOne | OneToMany | OneToZero;
1030
1003
  /**
1031
- * The mapping function provided by the `mapFn()` utility. This _fn_
1032
- * is intended to be used in two ways:
1033
- *
1034
- * 1. Iterative:
1035
- * ```ts
1036
- * const m = mapTo<I,O>(i => [ ... ]);
1037
- * // maps inputs to outputs
1038
- * const out = inputs.map(m);
1039
- * ```
1040
- * 2. Block:
1041
- * ```ts
1042
- * // maps inputs to outputs (filtering or splitting where appr.)
1043
- * const out2 = m(inputs);
1044
- * ```
1004
+ * Cardinality which expects a singular input which is allowed to be
1005
+ * _undefined_ or the expected type.
1045
1006
  */
1046
- declare type MapFn<I, O, C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = MapIR<C> extends "opt" ? <S extends MapFnInput<I, MapIR<C>, MapCard<C>>>(source?: S) => MapFnOutput<I, O, S, MapOR<C>, MapCard<C>> : <S extends MapFnInput<I, MapIR<C>, MapCard<C>>>(source: S) => MapFnOutput<I, O, S, MapOR<C>, MapCard<C>>;
1007
+ type Cardinality0 = ZeroToOne | ZeroToMany | OneToOne | OneToMany;
1047
1008
  /**
1048
- * **Mapper**
1049
- *
1050
- * A fully configured _mapper_ stemming from the **mapTo()** utility. It is both a mapping
1051
- * function and a dictionary which describes the mapper's properties.
1052
- * ```ts
1053
- * const m = mapTo.oneToOne().map( ... );
1054
- * const mapped = m(inputs);
1055
- * const mappedOver = inputs.map(m);
1056
- * ```
1057
- *
1058
- * Note: the root of a `Mapper` is the mapper function but
1059
- * this is combined with a dictionary of settings and types
1060
- * which you can use. For instance, look at the `fnSignature`
1061
- * property to get the _type_ signature of the map function.
1009
+ * Cardinality which expects a singular input -- which is allowed to be
1010
+ * _undefined_ -- and maps to 0,
1011
+ * 1, or many outputs.
1062
1012
  */
1063
- declare type Mapper<I = unknown, O = unknown, C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired> = FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = {
1064
- input: MapIR<C>;
1065
- output: MapOR<C>;
1066
- cardinality: MapCard<C>;
1067
- debug: boolean | string;
1068
- inputType: I;
1069
- outputType: O;
1070
- /**
1071
- * Provides the _type_ information for mapper function.
1072
- *
1073
- * Note: _this is just a **type**_ not the actual function which positioned
1074
- * at the root of the Mapper type
1075
- */
1076
- fnSignature: MapFn<I, O, C>;
1077
- } & MapFn<I, O, C>;
1013
+ type CardinalityFilter0 = ZeroToOne | ZeroToMany | OneToOne | OneToMany | OneToZero | ZeroToZero;
1014
+ type CardinalityExplicit = `${number}:${number}`;
1078
1015
  /**
1079
- * **MapInputFrom**
1080
- *
1081
- * Type utility which extracts the `I` type from a fully configured `Mapper`
1016
+ * Cardinality of any sort between two types
1082
1017
  */
1083
- declare type MapInputFrom<T extends Mapper> = T extends Mapper<infer I> ? I : never;
1018
+ type Cardinality = CardinalityFilter0 | CardinalityFilter1 | ManyToMany | ManyToOne | ManyToZero | CardinalityExplicit;
1019
+ type CardinalityTuple<T extends Cardinality> = UnionToTuple<T>;
1084
1020
  /**
1085
- * **MapOutputFrom**
1086
- *
1087
- * Type utility which extracts the output [`O`] type from a fully configured `Mapper`
1021
+ * The first or _input_ part of the Cardinality relationship
1088
1022
  */
1089
- declare type MapOutputFrom<T extends Mapper> = T extends Mapper<any, infer O> ? O : never;
1023
+ type CardinalityIn<T extends Cardinality> = T extends `${infer IN}:${string}` ? IN : never;
1090
1024
  /**
1091
- * **MapCardinalityFrom**
1092
- *
1093
- * Type utility which extracts _cardinality_ of a `Mapper`'s inputs to outputs
1025
+ * The second or _output_ part of the Cardinality relationship
1094
1026
  */
1095
- declare type MapCardinalityFrom<T extends Mapper> = T extends Mapper<any, any, infer C> ? C extends FinalizedMapConfig<OptRequired, infer Cardinality, OptRequired> ? Cardinality : never : never;
1027
+ type CardinalityOut<T extends Cardinality> = T extends `${string}:${infer OUT}` ? OUT : never;
1028
+ type CardinalityInput<T, C extends Cardinality> = CardinalityTuple<C>[0] extends 0 ? T | undefined : CardinalityTuple<C>[0] extends 1 ? T : T[];
1096
1029
 
1097
1030
  /**
1098
- * Given a dictionary of type `<T>`, this utility function will
1099
- * make the `<M>` generic property _mutable_ and all other _read-only_.
1031
+ * Converts a string literal into a _dasherized_ format while ignoring _exterior_ whitespace.
1100
1032
  *
1101
1033
  * ```ts
1102
- * // { foo: string, bar?: Readonly<number> }
1103
- * type Example = MutableProps<{
1104
- * foo: Readonly<string>,
1105
- * bar?: number
1106
- * }, "foo">;
1034
+ * // "foo-bar"
1035
+ * type Dash = Dasherize<"foo_bar">;
1036
+ * type Dash = Dasherize<"fooBar">;
1037
+ * type Dash = Dasherize<"FooBar">;
1038
+ * // "\n foo-bar \t"
1039
+ * type Dash = Dasherize<"\n foo bar \t">;
1107
1040
  * ```
1108
1041
  */
1109
- declare type MutableProps<T extends {}, M extends keyof T & string> = ExpandRecursively<Mutable<Pick<T, M>> & Readonly<Pick<T, Keys<T, M>>>>;
1042
+ type Dasherize<S extends string> = string extends S ? string : DashUppercase<Trim<LowerAllCaps<S>>> extends `${infer Begin}${"_" | " "}${infer Rest}` ? Dasherize<`${Lowercase<Begin>}-${Rest}`> : Lowercase<DashUppercase<Uncapitalize<Trim<LowerAllCaps<S>>>>>;
1110
1043
 
1111
1044
  /**
1112
- * Given a dictionary of type `<T>`, this utility function will
1113
- * make the `<R>` generic property _required_ (use a union to make
1114
- * more than one prop required).
1115
- *
1045
+ * Returns true or false value based on whether the string literal is capitalized.
1116
1046
  * ```ts
1117
- * // { foo: string, bar?: number }
1118
- * type Example = RequireProps<{foo?: string, bar?: number}, "foo">;
1047
+ * // true
1048
+ * type T2 = IsCapitalized<"One">;
1049
+ * // false
1050
+ * type T1 = IsCapitalized<"one">;
1051
+ * // "unknown"
1052
+ * const a: string = "Hi";
1053
+ * type T3 = IsCapitalized<typeof a>;
1119
1054
  * ```
1055
+ *
1056
+ * Note: _if the value passed in is a "string" then the result will be "unknown"_
1120
1057
  */
1121
- declare type RequireProps<T extends {}, R extends keyof T> = ExpandRecursively<Required<Pick<T, R>> & T>;
1058
+ type IsCapitalized<T extends string> = string extends T ? "unknown" : T extends Capitalize<T> ? true : false;
1122
1059
 
1123
- declare type LowerAlpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z";
1124
- /** Uppercase alphabetic character */
1125
- declare type UpperAlpha = Uppercase<LowerAlpha>;
1126
1060
  /**
1127
- * Alphabetical characters (upper and lower)
1128
- */
1129
- declare type Alpha = UpperAlpha | LowerAlpha;
1130
- declare type Whitespace = " " | "\n" | "\t";
1131
- declare type Punctuation = "." | "," | ";" | "!" | "?";
1061
+ * **KebabCase<T>** is an _alias_ for **Dasherize<T>**.
1062
+ * ```ts
1063
+ * // "foo-bar"
1064
+ * type Kebab = KebabCase<"foo_bar">;
1065
+ * type Kebab = KebabCase<"fooBar">;
1066
+ * type Kebab = KebabCase<"FooBar">;
1067
+ * // "\n foo-bar \t"
1068
+ * type Kebab = KebabCase<"\n foo bar \t">;
1069
+ * ``` */
1070
+ type KebabCase<T extends string> = Dasherize<T>;
1071
+
1072
+ type Consonant = "b" | "c" | "d" | "f" | "g" | "h" | "j" | "k" | "l" | "m" | "n" | "p" | "q" | "r" | "s" | "t" | "v" | "w" | "x" | "z" | "y";
1073
+ type Exceptions = "photo => photos" | "piano => pianos" | "halo => halos" | "foot => feet" | "man => men" | "woman => women" | "person => people" | "mouse => mice" | "series => series" | "sheep => sheep" | "money => monies" | "deer => deer";
1074
+ type SingularException<T = Exceptions> = T extends `${infer SINGULAR} => ${infer PLURAL}` ? SINGULAR : never;
1075
+ type PluralException<T extends SingularException, E extends Exceptions = Exceptions> = E extends `${T} => ${infer PLURAL}` ? PLURAL : never;
1076
+ type SingularNoun = "s" | "sh" | "ch" | "x" | "z" | "o";
1077
+ type F = "f" | "fe";
1078
+ type Y = `${Consonant}y`;
1079
+ type RemoveTrailingY<T> = T extends `${infer HEAD}y` ? HEAD : T;
1080
+ /** validates that a word ends with a pluralization exception */
1081
+ type isException<T extends string> = T extends SingularException ? T : never;
1082
+ /** validates that a string literal ends in "is" */
1083
+ type EndsIn_IS<T extends string> = T extends `${infer HEAD}is` ? T : never;
1084
+ /** validates that a string literal is a singular noun */
1085
+ type EndsInSingularNoun<T extends string> = T extends `${infer HEAD}${SingularNoun}` ? T : never;
1086
+ /** validates that a string literal ends in "f" or "fe" */
1087
+ type EndsIn_F<T extends string> = T extends `${infer HEAD}${F}` ? T : never;
1088
+ /** validates that a string literal ends a consonant followed by "y" */
1089
+ type EndsIn_Y<T extends string> = T extends `${infer HEAD}${Y}` ? T : never;
1132
1090
  /**
1133
- * Characters which typically are used to separate words (but not including a space)
1091
+ * strings which end in the letters "is" should have an "es" added to the end
1134
1092
  */
1135
- declare type StringDelimiter = "_" | "-" | "/" | "\\";
1136
- declare type OpeningBracket = "(" | "[" | "{";
1137
- declare type ClosingBracket = ")" | "]" | "}";
1093
+ type PluralizeEndingIn_IS<T extends string> = T extends `${infer HEAD}is` ? `${HEAD}ises` : T;
1138
1094
  /**
1139
- * Opening and closing parenthesis
1095
+ * singular nouns should have "es" added to the end
1140
1096
  */
1141
- declare type Parenthesis = "(" | ")";
1097
+ type PluralizeEndingSingularNoun<T extends string> = T extends `${infer HEAD}${SingularNoun}` ? `${T}es` : T;
1142
1098
  /**
1143
- * Opening and closing brackets
1099
+ * strings which end in the letters "f" or "fe" should have "ves" replace the ending
1144
1100
  */
1145
- declare type Bracket = OpeningBracket | ClosingBracket;
1101
+ type PluralizeEnding_F<T extends string> = T extends `${infer HEAD}${F}` ? `${HEAD}ves` : T;
1146
1102
  /**
1147
- * Numeric string characters
1103
+ * singular nouns should have "es" added to the end
1148
1104
  */
1149
- declare type NumericString = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
1105
+ type PluralizeEndingIn_Y<T extends string> = T extends `${infer HEAD}${Y}` ? `${RemoveTrailingY<T>}ies` : T;
1106
+ type Pluralize<T extends string> = T extends isException<T> ? PluralException<T> : T extends EndsIn_IS<T> ? PluralizeEndingIn_IS<T> : T extends EndsInSingularNoun<T> ? PluralizeEndingSingularNoun<T> : T extends EndsIn_F<T> ? PluralizeEnding_F<T> : T extends EndsIn_Y<T> ? PluralizeEndingIn_Y<T> : `${T}s`;
1107
+
1108
+ /** convert space to dash */
1109
+ type SpaceToDash<T extends string> = T extends `${infer Begin}${" "}${infer Rest}` ? SpaceToDash<`${Begin}-${Rest}`> : T;
1150
1110
  /**
1151
- * Any alphabetic or numeric string character
1152
- */
1153
- declare type AlphaNumeric = Alpha | NumericString;
1154
- declare type SpecialCharacters = "@" | "~" | "^" | "#" | "&" | "*";
1155
- /**
1156
- * Non-alphabetic characters including whitespace, string numerals, and
1157
- */
1158
- declare type NonAlpha = Whitespace | Punctuation | NumericString | Bracket | SpecialCharacters;
1111
+ * Converts a string literal type to _snake_case_.
1112
+ * ```ts
1113
+ * // "foo_bar"
1114
+ * type T = SnakeCase<"fooBar">;
1115
+ * type T = SnakeCase<"FooBar">;
1116
+ * type T = SnakeCase<"foo-bar">;
1117
+ * type T = SnakeCase<"\n foo bar \t">;
1118
+ * ``` */
1119
+ type SnakeCase<S extends string> = string extends S ? string : DashUppercase<Uncapitalize<SpaceToDash<Trim<LowerAllCaps<S>>>>> extends `${infer Begin}${"-"}${infer Rest}` ? SnakeCase<`${Lowercase<Begin>}_${Rest}`> : Lowercase<DashUppercase<Uncapitalize<Trim<LowerAllCaps<S>>>>>;
1159
1120
 
1121
+ type NetworkProtocol = "http" | "https" | "file" | "ws" | "wss";
1160
1122
  /**
1161
- * Extracts the _required_ keys in the object's type. You also may
1162
- * optionally filter by the _value_ of the key.
1123
+ * A literal variant of _string_ which is meant to represent a domain name
1124
+ * (e.g., `www.someplace.com`, etc.)
1163
1125
  */
1164
- declare type RequiredKeys<T extends object, V extends any = any> = {
1165
- [K in keyof T]-?: {} extends {
1166
- [P in K]: T[K];
1167
- } ? never : T[K] extends V ? K : never;
1168
- }[keyof T];
1126
+ type DomainName = `${AlphaNumeric}${string}.${AlphaNumeric}${string}` | `${AlphaNumeric}${string}.${AlphaNumeric}${string}.${string}` | `${AlphaNumeric}${string}.${AlphaNumeric}${string}.${string}.${string}`;
1127
+ type RelativeUrl = `${VariableName | "/"}`;
1169
1128
  /**
1170
- * Extracts the intersecting/common keys to two objects
1129
+ * A literal variant of _string_ which forces a string to follow conventions
1130
+ * for a fully qualified URL like `https://google.com`. It can't ensure the
1131
+ * type is fully valid but does help to avoid some typos.
1171
1132
  */
1172
- declare type IntersectingKeys<T extends Record<string, any> | readonly string[], U extends Record<string, any> | readonly string[]> = {
1173
- [K in keyof T]: K extends Keys<U> ? K : never;
1174
- }[keyof T];
1133
+ type FullyQualifiedUrl = `${NetworkProtocol}://${Ipv4 | DomainName}/${string}`;
1134
+ type UrlBuilder = (<P extends NetworkProtocol, D extends DomainName, B extends RelativeUrl>(protocol: P, domain: D, basePath: B) => `${P}://${D}/${B}`) | (<U extends RelativeUrl>(url: U) => U);
1135
+
1175
1136
  /**
1176
- * Extracts the _optional_ keys in the object's type. You also may
1177
- * optionally filter by the _value_ of the key.
1137
+ * Given a dictionary of key/values, where the value is a function, this
1138
+ * type utility will maintain the keys but change the values to whatever
1139
+ * the `ReturnType` of the function was.
1140
+ * ```ts
1141
+ * const api = {
1142
+ * val: 42,
1143
+ * hi: (name: string) => `hi ${name}`,
1144
+ * bye: (name: string) => `bye ${name}`
1145
+ * };
1146
+ * // { hi: string; bye: string }
1147
+ * type Test = UnwrapValue<typeof api>
1148
+ * // { val: number; foo: string; bar: string }
1149
+ * type Test2 = UnwrapValue<typeof api, false>
1150
+ * ```
1178
1151
  */
1179
- declare type OptionalKeys<T extends object, V extends any = any> = {
1180
- [K in keyof T]-?: {} extends {
1181
- [P in K]: T[K];
1182
- } ? V extends T[K] ? K : never : never;
1183
- }[keyof T];
1152
+ type DictPartialApplication<T extends Record<string, any>, I extends boolean = true> = SimplifyObject<{
1153
+ [K in keyof T]: T[K] extends (...args: any[]) => any ? Record<K, ReturnType<T[K]>> : true extends I ? never : Record<K, T[K]>;
1154
+ }[keyof T]>;
1155
+
1184
1156
  /**
1185
- * The _keys_ on a given object `T` which have a literal value of `W`.
1157
+ * Allow a dictionary have it's value's type changed to `T` while maintaining the keys in
1158
+ * the original object `I` so long as the original value for the KV pair extends `V`.
1159
+ *
1160
+ * If `V` is not specified then it defaults to _any_ and therefore all KVs are preserved.
1186
1161
  *
1187
- * Optionally, you may provide a generic `E` to exclude certain keys in
1188
- * result set.
1189
1162
  * ```ts
1190
- * // "foo"
1191
- * type Str = KeysWithValue<{ foo: "hi"; bar: 5 }>;
1163
+ * type Obj = { foo: "hello", bar: 42, baz: () => "world" };
1164
+ * // { foo: number, bar: number, baz: number };
1165
+ * type AllNumbers = DictChangeValue<Obj, number>;
1166
+ * // { foo: number }
1167
+ * type StringToBool = DictChangeValue<Obj, boolean, string>
1192
1168
  * ```
1193
1169
  */
1194
- declare type KeysWithValue<W extends any, T extends object> = {
1195
- [K in keyof T]: T[K] extends W ? Readonly<K> : never;
1196
- }[keyof T];
1197
- /**
1198
- * A `PrivateKey` must start with a `_` character and then follow with
1199
- * an alphabetic character
1200
- */
1201
- declare type PrivateKey = `_${Alpha}${string}`;
1170
+ type DictChangeValue<
1171
+ /** the object who's value-type we're changing */
1172
+ I extends Record<string, any>,
1173
+ /** the return type that functions should be modified to have */
1174
+ T extends any,
1202
1175
  /**
1203
- * Keys on an object which have a `_` character as first part of the
1204
- * name are considered private and this utility will create a union
1205
- * of all the keys in this category.
1176
+ *The type we expect in the value; if the value extends type `V` then the value will
1177
+ * be converted to type `O`; if not then the KV pair will be discarded
1206
1178
  */
1207
- declare type PrivateKeys<T extends object> = {
1208
- [K in keyof T]: K extends `_${string}` ? K : never;
1209
- }[keyof T];
1179
+ V extends any = any> = SimplifyObject<{
1180
+ [K in keyof I]: I[K] extends V ? Record<K, T> : never;
1181
+ }[keyof I]>;
1182
+
1210
1183
  /**
1211
- * **PublicKeys**
1184
+ * **DictPrependWithFn**
1212
1185
  *
1213
- * Builds a union type of all keys which are "public" where a public
1214
- * key is any key which _does not_ start with the `_` character.
1186
+ * Given a strongly typed object `<T>`, this utility will inject a function call with
1187
+ * arguments `<A>` and then return what had subsequently been the value of the property.
1188
+ *
1189
+ * Should you only want to apply this treatment to _some_ of the properties you can
1190
+ * pass in a value `<E>` which will ensure that only properties which _extend_ `E` will be
1191
+ * modified.
1215
1192
  */
1216
- declare type PublicKeys<T extends object> = {
1217
- [K in keyof T]: K extends `_${string}` ? never : K;
1218
- }[keyof T];
1219
- declare type StringKeys<T extends object> = {
1220
- [K in keyof T]: K extends string ? Readonly<K> : never;
1221
- }[keyof T];
1193
+ type DictPrependWithFn<T extends Record<string, any>, A extends any[], E extends any = any> = SimplifyObject<{
1194
+ [K in keyof T]: T[K] extends E ? Record<K, (...args: A) => T[K]> : Record<K, T[K]>;
1195
+ }[keyof T]>;
1196
+
1222
1197
  /**
1223
- * The keys of an object which _are not_ a string type
1198
+ * **DictReturnValues**
1199
+ *
1200
+ * A type utility which receives an object `<T>` and then modifies
1201
+ * the return type of any properties which are a function to have this
1202
+ * new **ReturnType** `<R>`. Optionally you can specify a particular return type which
1203
+ * you are targeting and then
1224
1204
  */
1225
- declare type NonStringKeys<T extends object> = {
1226
- [K in keyof T]: K extends string ? never : Readonly<K>;
1227
- }[keyof T];
1228
- declare type NumericKeys<T extends object> = {
1229
- [K in keyof T]: K extends number ? Readonly<K> : never;
1230
- }[keyof T];
1231
- declare type NonNumericKeys<T extends object> = {
1232
- [K in keyof T]: K extends number ? never : Readonly<K>;
1233
- }[keyof T];
1205
+ type DictReturnValues<
1206
+ /** the object which we expect to have props with function values */
1207
+ T extends Record<string, any>,
1208
+ /** the return type that functions should be modified to have */
1209
+ R extends any,
1210
+ /** optionally this utility can target only functions with a certain existing return value */
1211
+ O extends (...args: any[]) => any = (...args: any[]) => any> = SimplifyObject<{
1212
+ [K in keyof T]: T[K] extends O ? T[K] extends (...args: infer A) => any ? Record<K, (...args: A) => R> : Record<K, T[K]> : Record<K, T[K]>;
1213
+ }[keyof T]>;
1214
+
1234
1215
  /**
1235
- * **RequiredProps**
1236
- *
1237
- * Reduces an object type to only key/value pairs where the key is required
1216
+ * Get the type of a property of an object:
1217
+ * ```ts
1218
+ * const car = { make: "Chevy", model: "Malibu", }
1219
+ * ```
1238
1220
  */
1239
- declare type RequiredProps<T extends object> = Pick<T, RequiredKeys<T>>;
1221
+ type Get<T, K> = K extends `${infer FK}.${infer L}` ? FK extends keyof T ? Get<T[FK], L> : never : K extends keyof T ? T[K] : never;
1222
+
1240
1223
  /**
1241
- * **OptionalProps**
1242
- *
1243
- * Reduces an object to only key/value pairs where the key is optional
1224
+ * Expresses whether an option is "opt" (optional) or "req" (required)
1244
1225
  */
1245
- declare type OptionalProps<T extends object> = Pick<T, OptionalKeys<T>>;
1226
+ type OptRequired = "opt" | "req";
1227
+
1228
+ declare const DEFAULT_ONE_TO_MANY_MAPPING: FinalizedMapConfig<"req", "I -> O[]", "opt">;
1229
+ declare const DEFAULT_ONE_TO_ONE_MAPPING: FinalizedMapConfig<"req", "I -> O", "req">;
1230
+ declare const DEFAULT_MANY_TO_ONE_MAPPING: FinalizedMapConfig<"req", "I[] -> O", "req">;
1231
+ type DefaultOneToManyMapping = typeof DEFAULT_ONE_TO_MANY_MAPPING;
1232
+ type DefaultOneToOneMapping = typeof DEFAULT_ONE_TO_ONE_MAPPING;
1233
+ type DefaultManyToOneMapping = typeof DEFAULT_MANY_TO_ONE_MAPPING;
1246
1234
  /**
1247
- * **WithValue**
1235
+ * **mapTo** _utility_
1248
1236
  *
1249
- * Reduces an object's type down to only those key/value pairs where the
1250
- * value is of type `W`.
1237
+ * This utility -- by default -- creates a strongly typed 1:M data mapper which maps from one
1238
+ * known source `I` to any array of another `O[]`:
1251
1239
  * ```ts
1252
- * const foo = { a: 1, b: "hi", c: () => "hello" }
1253
- * // { c: () => "hello" }
1254
- * type W = WithValue<Function, typeof foo>
1240
+ * const mapper = mapTo<I, O>(i => [{
1241
+ * foo: i.bar
1242
+ * }]);
1255
1243
  * ```
1256
1244
  */
1257
- declare type WithValue<W extends any, T extends object, E extends any = undefined> = undefined extends E ? Pick<T, KeysWithValue<W, T>> : Omit<Pick<T, KeysWithValue<W, T>>, KeysWithValue<E, T>>;
1258
- /**
1259
- * Reduces an object to only the key/value pairs where the key is a
1260
- * string.
1261
- */
1262
- declare type WithStringKeys<T extends object> = Omit<T, NonStringKeys<T>>;
1245
+ declare const mapToFn: ConfiguredMap<DefaultOneToManyMapping>["map"];
1263
1246
  /**
1264
- * Reduces an object to only the key/value pairs where the key is numeric.
1247
+ * Provides a `config` method which allows the relationships between _inputs_
1248
+ * and _outputs_ to be configured.
1265
1249
  */
1266
- declare type WithNumericKeys<T extends object> = Omit<T, NonNumericKeys<T>>;
1267
-
1250
+ declare const mapToDict: MapperApi;
1268
1251
  /**
1269
- * **withValue**
1252
+ * **mapTo** _utility_
1270
1253
  *
1271
- * Reduces a dictionary object -- in both _type_ and _run-time_ structure -- to only those
1272
- * key/value pairs which have a specified value. For instance:
1254
+ * This utility creates a strongly typed data mapper which maps from one
1255
+ * known source `I` to another `O`.
1273
1256
  *
1257
+ * Signatures:
1274
1258
  * ```ts
1275
- * const obj = { foo: 1, bar: 2, message: "hi there" };
1276
- * // { message: "hi there" }
1277
- * const onlyStrings = withValue(t => t.string)(obj);
1278
- * // { foo: 1 }
1279
- * const justOne = withValue(t => t.literal(1))(obj);
1259
+ * const defMap = mapTo<I,O>( ... );
1260
+ * const configured = mapTo.config({ output: "req" }).map<I,O>( ... );
1261
+ * const one2one = mapTo.oneToOne().map<I,O>( ... );
1262
+ * const many2one = mapTo.manyToOne().map<I,O>( ... );
1280
1263
  * ```
1281
- *
1282
- * Note: _often useful to provide run-time type profiles with the_ `inferredType` _utility_
1283
1264
  */
1284
- declare function withValue<T extends any, V extends Function>(td: TypeDefinition<T, V>): <N extends Narrowable, R extends Record<string, N>>(obj: R) => ExpandRecursively<Pick<R, KeysWithValue<T, R>>>;
1265
+ declare const mapTo: (<I, O>(map: (source: I) => O[]) => Mapper<I, O, FinalizedMapConfig<"req", "I -> O[]", "opt">>) & MapperApi;
1285
1266
 
1286
1267
  /**
1287
- * **RuleDefinition**
1288
- *
1289
- * A rule definition is the typing for the fluent API surface that is built up
1290
- * with the **ruleset** utility.
1268
+ * Expresses relationship between inputs/outputs:
1291
1269
  */
1292
- declare type RuleDefinition<
1293
- /** the data which will be evaluated on rule execution */
1294
- T extends object,
1295
- /** the optional props -- as a union type -- which must be defined per the rule */
1296
- H extends string = "",
1297
- /** the key/values which will be evaluated on execution (wide type) */
1298
- E extends Partial<SameKeys<T>> = {},
1299
- /** the key/values which will be evaluated on execution (narrow type) */
1300
- N extends Partial<SameKeys<T>> = {}> = {
1301
- /**
1302
- * sets up a true/false check that a given property is defined; this
1303
- * condition can only be applied to _optional_ properties.
1304
- */
1305
- has(optProp: OptionalKeys<T>): RuleDefinition<T, H & typeof optProp, E, N>;
1306
- /**
1307
- * Validates that a given property extends a certain value's type; comparison
1308
- * is made assuming "wide types".
1309
- */
1310
- equals<K extends keyof T, V extends Pick<T, K>>(prop: K, value: V): RuleDefinition<T, H, E & Record<K, V>, N>;
1270
+ declare enum MapCardinality {
1271
+ /** every input results in 0:M outputs */
1272
+ OneToMany = "I -> O[]",
1273
+ /** every input results in 0:1 outputs */
1274
+ OneToOne = "I -> O",
1275
+ /** every input is an array of type I and reduced to a single O */
1276
+ ManyToOne = "I[] -> O"
1277
+ }
1278
+ type MapCardinalityIllustrated = EnumValues<MapCardinality>;
1279
+ /**
1280
+ * The _user_ configuration of a **mapTo** mapper function
1281
+ * which will be finalized by merging it with the appropriate
1282
+ * default mapping type.
1283
+ */
1284
+ interface MapConfig<IR extends OptRequired | undefined = undefined, D extends MapCardinalityIllustrated | undefined = undefined, OR extends OptRequired | undefined = undefined> {
1285
+ input?: IR;
1286
+ output?: OR;
1287
+ cardinality?: D;
1311
1288
  /**
1312
- * Validates that a given property extends a certain value's type; comparison
1313
- * is made assuming "narrow types". This is only available for props which
1314
- * expose a
1289
+ * Whether calls to the final `MapFn` will be logged to stderr
1290
+ * for debugging purposes. Defaults to false; if you specify
1291
+ * a _string_ for a value that will be sent to stderr along
1292
+ * with other debugging info.
1315
1293
  */
1316
- narrowlyEquals<K extends keyof T, V extends Pick<T, K>>(prop: K, value: V): RuleDefinition<T, H, E, N & Record<K, V>>;
1317
- };
1294
+ debug?: boolean | string;
1295
+ }
1318
1296
  /**
1319
- * **DynamicRule**
1320
- *
1321
- * A dynamic rule allows type and runtime validation of a data structure
1322
- * which extends a known `State`. It then returns the literal type `true`
1323
- * or `false`.
1297
+ * A finalized configuration of a **mapTo** mapper functions cardinality
1298
+ * relationships between _inputs_ and _outputs_.
1324
1299
  *
1325
- * ```ts
1326
- * type State = { id?: string; favorite: boolean; color: string };
1327
- * // type-safe way to check whether optional prop is actually set
1328
- * const rule: DynamicRule<State> = s => s
1329
- * .has("id")
1330
- * .equals("favorite", true)
1331
- * .equals("color", "red");
1332
- * ```
1300
+ * Note: _this configuration does _not_ yet include the actual mapping
1301
+ * configuration between the input and output._
1333
1302
  */
1334
- declare type DynamicRule<TState extends any, TResult extends true | false> = (rule: TypeCondition<any, TState>) => TResult;
1303
+ type FinalizedMapConfig<IR extends OptRequired = MapIR<DefaultOneToManyMapping>, D extends MapCardinalityIllustrated = MapCard<DefaultOneToManyMapping>, OR extends OptRequired = MapOR<DefaultOneToManyMapping>> = Required<Omit<MapConfig<IR, D, OR>, "debug">> & {
1304
+ finalized: true;
1305
+ debug: boolean | string;
1306
+ };
1335
1307
  /**
1336
- * **DynamicRuleSet**
1337
- *
1338
- * A function which accepts the agreed `TState` generic as input and returns a discrete
1339
- * `true` or `false` value.
1308
+ * User configuration exposed by a config function which specifies the
1309
+ * cardinality already (e.g., `oneToMany()`, `manyToOne()`)
1340
1310
  */
1341
- declare type DynamicRuleSet<TState extends any, TRules extends Record<string, TypeCondition<any, TState>>> = (rules: TRules) => true | false;
1342
-
1343
- declare type RuntimeType<T> = {
1344
- __kind: "type";
1345
- type: T;
1346
- is: TypeGuard<T>;
1347
- };
1348
- declare type RuntimeProp<P extends Readonly<PropertyKey>, T extends RuntimeType<any>> = {
1349
- __kind: "prop";
1350
- key: Readonly<P>;
1351
- valueType: Readonly<T["type"]>;
1311
+ type MapCardinalityConfig<IR extends OptRequired | undefined, OR extends OptRequired | undefined> = {
1312
+ /** whether we the input can _optionally_ be an `undefined` value or not */
1313
+ input?: IR;
1314
+ /** whether we the output can _optionally_ be an `undefined` value or not */
1315
+ output?: OR;
1352
1316
  /**
1353
- * Provides the _type_ to the type system when used with `typeof`.
1354
- *
1355
- * ```ts
1356
- * const t = number();
1357
- * // number
1358
- * type T = typeof t.type;
1359
- * ```
1360
- *
1361
- * **Note:** _the runtime system will get a string equivalent name:_
1362
- * ```ts
1363
- * const t = number();
1364
- * // "number"
1365
- * console.log(t.type);
1366
- * ```
1317
+ * Whether calls to the final `MapFn` will be logged to stderr
1318
+ * for debugging purposes. Defaults to false; if you set to a string
1319
+ * value than this will be echoed out with stderr.
1367
1320
  */
1368
- type: Record<P, T["type"]>;
1369
- is: TypeGuard<Record<P, T["type"]>>;
1321
+ debug?: boolean | string;
1370
1322
  };
1371
- declare type TypeOptions<T extends Partial<object> = {}> = {
1372
- /** each type has a default type guard but you can override if you need to be more specific */
1373
- typeGuard?: TypeGuard<T>;
1374
- } & T;
1375
-
1376
- /**
1377
- * Validates that a given type extends another and returns `true` or `false` type
1378
- */
1379
- declare type ExpectExtends<VALUE, EXPECTED> = EXPECTED extends VALUE ? true : false;
1380
- /**
1381
- * Validates that a given type extends another and returns `any` or `never` as a type
1382
- */
1383
- declare type AssertExtends<VALUE, EXPECTED> = EXPECTED extends VALUE ? any : never;
1384
1323
  /**
1385
- * Give a type `TValue` and a comparison type `TExtends`
1386
- */
1387
- declare type IfExtendsThen<VALUE, EXPECTED, THEN> = EXPECTED extends VALUE ? THEN : never;
1388
-
1389
- /**
1390
- * Indicates whether `T` has _all_ uppercase characters in it.
1391
- * ```ts
1392
- * // true
1393
- * type T = AllCaps<"FOOBAR">;
1394
- * // false
1395
- * type T = AllCaps<"FooBar">;
1396
- * // "unknown"
1397
- * type T = AllCaps<string>;
1398
- * ```
1399
- */
1400
- declare type AllCaps<T extends string> = string extends T ? "unknown" : T extends Uppercase<T> ? true : false;
1401
-
1402
- /**
1403
- * **Break<T,D>**
1404
- *
1405
- * Takes a string `T`, and splits it into a tuple of the form `[F, R]`.
1406
- * ```ts
1407
- * // ["the", " long and winding road"]
1408
- * type T1 = Break<"the long and winding road", " ">;
1409
- * // ["there", " I was, there I was"]
1410
- * type T2 = Break<"there I was, there I was", " ">;
1411
- * ```
1412
- */
1413
- declare type Break<T extends string, D extends string> = (string extends T ? [string, string] : (T extends `${infer F}${D}${infer _R}` ? (F extends `${infer _X}${D}${infer _Y}` ? never : (T extends `${F}${infer R}` ? [F, R] : never)) : [T, ""]));
1414
-
1415
- /**
1416
- * Concatenates two arrays (of literals).
1417
- * ```ts
1418
- * // [ "foo", "bar", "baz" ]
1419
- * type T = ArrConcat<["foo"], ["bar", "baz"]>;
1420
- * ```
1421
- */
1422
- declare type ArrConcat<A extends any[], B extends any[]> = [...A, ...B];
1423
-
1424
- /**
1425
- * Type utility which takes a string `S` and replaces the substring `W` with `P`.
1426
- * ```ts
1427
- * const fooy = "fooy";
1428
- * // "Foo"
1429
- * type Foo = Replace<typeof fooy, "y", "">;
1430
- * ```
1324
+ * **ConfiguredMap**
1431
1325
  *
1432
- * Note: _the first match is replaced and all subsequent matches are ignored_
1433
- */
1434
- declare type Replace<S extends string, W extends string, P extends string> = S extends "" ? "" : W extends "" ? S : S extends `${infer F}${W}${infer E}` ? `${F}${P}${E}` : S;
1435
-
1436
- /**
1437
- * Trims off whitespace on left of string
1438
- * ```ts
1439
- * // "foobar "
1440
- * type T = TrimLeft<"\n\t foobar ">;
1441
- * // string
1442
- * type T = TrimLeft<string>;
1443
- * ```
1326
+ * A partial application of the mapTo() utility which has expressed the
1327
+ * configuration of the _inputs_ and _outputs_ and provides a `.map()`
1328
+ * method which allows the user configure the specifics of the mapping.
1444
1329
  */
1445
- declare type TrimLeft<S extends string> = string extends S ? string : S extends `${Whitespace}${infer Right}` ? TrimLeft<Right> : S;
1446
-
1330
+ type ConfiguredMap<C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = {
1331
+ map: <I, O>(map: MapTo<I, O, C>) => Mapper<I, O, C>;
1332
+ input: MapIR<C>;
1333
+ cardinality: MapCard<C>;
1334
+ output: MapOR<C>;
1335
+ debug: boolean | string;
1336
+ };
1447
1337
  /**
1448
- * Provides the _left_ whitespace of a string
1449
- * ```ts
1450
- * // "\n\t "
1451
- * type T = LeftWhitespace<"\n\t foobar">;
1452
- * ```
1338
+ * Extracts the IR, Cardinality, and OR generics from a FinalizedMapConfig
1453
1339
  */
1454
- declare type LeftWhitespace<S extends string> = string extends S ? string : Replace<S, TrimLeft<S>, "">;
1455
-
1340
+ type DecomposeMapConfig<M extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = M extends MapConfig<infer IR, infer D, infer OR> ? IR extends OptRequired | undefined ? D extends MapCardinalityIllustrated | undefined ? OR extends OptRequired | undefined ? [IR, D, OR] : never : never : never : M extends FinalizedMapConfig<infer IR, infer D, infer OR> ? IR extends OptRequired ? D extends MapCardinalityIllustrated ? OR extends OptRequired ? [IR, D, OR] : never : never : never : never;
1341
+ /** extracts IR from a `FinalizedMapConfig` */
1342
+ type MapIR<T extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = DecomposeMapConfig<T>[0];
1456
1343
  /**
1457
- * Trims off whitespace on left of string
1458
- * ```ts
1459
- * // "\n foobar"
1460
- * type T = TrimRight<"\n foobar \t">;
1461
- * // string
1462
- * type T = TrimRight<string>;
1463
- * ```
1344
+ * extracts the MapCardinality from a `FinalizedMapConfig`
1464
1345
  */
1465
- declare type TrimRight<S extends string> = string extends S ? string : S extends `${infer Right}${Whitespace}` ? TrimRight<Right> : S;
1466
-
1346
+ type MapCard<T extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = DecomposeMapConfig<T>[1];
1347
+ /** extracts OR from a `FinalizedMapConfig` */
1348
+ type MapOR<T extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = DecomposeMapConfig<T>[2];
1467
1349
  /**
1468
- * Provides the _left_ whitespace of a string
1469
- * ```ts
1470
- * // "\n\t "
1471
- * type T = LeftWhitespace<"\n\t foobar">;
1472
- * ```
1350
+ * Merges the types of a userland configuration with a default configuration
1473
1351
  */
1474
- declare type RightWhitespace<S extends string> = string extends S ? string : Replace<S, TrimRight<S>, "">;
1475
-
1352
+ type AsFinalizedConfig<U extends MapConfig<OptRequired | undefined, MapCardinalityIllustrated | undefined, OptRequired | undefined>, D extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = TypeDefault<U, D> extends FinalizedMapConfig<infer IR, infer C, infer OR> ? FinalizedMapConfig<IR, C, OR> : never;
1353
+ type MapperApi = {
1354
+ /**
1355
+ * Provides opportunity to configure _input_, _output_, and _cardinality_
1356
+ * prior to providing a mapping function.
1357
+ *
1358
+ * Note: _the defaults for configuration are defined by the_ `DEFAULT_ONE_TO_MANY_MAPPING`
1359
+ * _constant made available as a symbol from this library._
1360
+ */
1361
+ config: <C extends MapConfig<OptRequired, //
1362
+ MapCardinalityIllustrated, OptRequired>>(config: C) => ConfiguredMap<AsFinalizedConfig<C, //
1363
+ DefaultOneToManyMapping>>;
1364
+ /**
1365
+ * Provides a nice 1:1 ratio between the input and output.
1366
+ *
1367
+ * By default the input and output are considered to be _required_
1368
+ * properties but this can be changed with the options hash provided.
1369
+ * ```ts
1370
+ * const mapper = mapTo.oneToOne().map(...);
1371
+ * // add in ability to filter out some inputs
1372
+ * const mapAndFilter = mapTo.oneToOne({ output: "opt" })
1373
+ * ```
1374
+ */
1375
+ oneToOne: <C extends MapCardinalityConfig<OptRequired, OptRequired>>(config?: C) => ConfiguredMap<AsFinalizedConfig<C, //
1376
+ DefaultOneToOneMapping>>;
1377
+ /**
1378
+ * **manyToOne** _mapping_
1379
+ *
1380
+ * Provides a configuration where multiple inputs `I[]` will be mapped to a
1381
+ * single output `O`.
1382
+ *
1383
+ * Choosing this configuration will, by default, set both input and output
1384
+ * to be "required" but you can change this default if you so choose.
1385
+ */
1386
+ manyToOne: <C extends MapCardinalityConfig<OptRequired | undefined, //
1387
+ //
1388
+ OptRequired | undefined>>(config?: C) => ConfiguredMap<AsFinalizedConfig<C, //
1389
+ DefaultManyToOneMapping>>;
1390
+ oneToMany: <C extends MapCardinalityConfig<OptRequired | undefined, //
1391
+ //
1392
+ OptRequired | undefined>>(config?: C) => ConfiguredMap<AsFinalizedConfig<C, //
1393
+ DefaultOneToManyMapping>>;
1394
+ };
1395
+ type MapInput<I, //
1396
+ IR extends OptRequired, C extends MapCardinalityIllustrated> = C extends MapCardinality.OneToMany | "I -> O[]" ? IR extends "opt" ? I | undefined : I : C extends MapCardinality.OneToOne | "I -> O" ? IR extends "opt" ? I | undefined : I : C extends MapCardinality.ManyToOne | "I[] -> O" ? IR extends "opt" ? I[] | undefined : I[] : never;
1397
+ type MapOutput<O, //
1398
+ OR extends OptRequired, C extends MapCardinalityIllustrated> = C extends MapCardinality.OneToMany | "I -> O[]" ? OR extends "opt" ? O[] : [O, ...O[]] : C extends MapCardinality.OneToOne | "I -> O" ? OR extends "opt" ? O | null : O : C extends MapCardinality.ManyToOne | "I[] -> O" ? OR extends "opt" ? O | null : O : never;
1476
1399
  /**
1477
- * Type utility that provides the _length_ of a given string type in a way which
1478
- * is _not_ limited to TS's recursive string length of roughly 48.
1400
+ * **MapTo<I, O>**
1479
1401
  *
1480
- * ```ts
1481
- * // 3
1482
- * type Three = StringLength<"foo">;
1483
- * ```
1484
- */
1485
- declare type StringLength<S extends string, R extends number[] = []> = S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer _Sevebnth}${infer _Eighth}${infer _Ninth}${infer _Tenth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer _Sevebnth}${infer _Eighth}${infer _Ninth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer _Sevebnth}${infer _Eighth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer _Sevebnth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}${infer _Sixth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer _Fifth}}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer _Fourth}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer _Third}${infer Rest}` ? StringLength<Rest, [...R, 1, 1, 1]> : S extends `${infer _First}${infer _Second}${infer Rest}` ? StringLength<Rest, [...R, 1, 1]> : S extends `${infer _First}${infer Rest}` ? StringLength<Rest, [...R, 1]> : [...R]["length"];
1486
-
1487
- /**
1488
- * Trims off blank spaces, `\n` and `\t` characters from both sides of a _string literal_.
1489
- * ```ts
1490
- * // "foobar"
1491
- * type T = Trim<"\n\t foobar ">;
1492
- * // string
1493
- * type T = Trim<string>;
1494
- * ```
1495
- */
1496
- declare type Trim<S extends string> = string extends S ? string : S extends `${Whitespace}${infer Right}` ? Trim<Right> : S extends `${infer Left}${Whitespace}` ? Trim<Left> : S;
1497
-
1498
- /**
1499
- * An email address
1500
- */
1501
- declare type Email = `${string}@${string}.${string}`;
1502
- declare type Zip5 = `${NumericString}${NumericString}${string}${NumericString}`;
1503
- declare type Zip4 = `${NumericString}${string}`;
1504
- /**
1505
- * A relatively strong type for Zip5 or Zip5+4 zip codes
1506
- */
1507
- declare type ZipCode = Zip5 | `${Zip5}-${Zip4}`;
1508
-
1509
- /**
1510
- * If **ALL CAPS** it converts to all lowercase; if not then it does nothing */
1511
- declare type LowerAllCaps<T extends string> = AllCaps<T> extends true ? Lowercase<T> : T;
1512
-
1513
- declare type Delimiter = "_" | "-" | " ";
1514
- /** convert all delimiters to dashes */
1515
- declare type DashDelim<T extends string> = T extends `${infer Begin}${" "}${infer Rest}` ? DashDelim<`${Begin}-${Rest}`> : T extends `${infer Begin}${"_"}${infer Rest}` ? DashDelim<`${Begin}-${Rest}`> : T;
1516
- /**
1517
- * Converts a string literal type to a **PascalCase** representation.
1518
- * ```ts
1519
- * // "FooBar"
1520
- * type T = PascalCase<"fooBar">;
1521
- * type T = PascalCase<"foo-bar">;
1522
- * type T = PascalCase<"foo_bar">;
1523
- * type T = PascalCase<"\n foo_bar \t">;
1524
- * ```
1525
- */
1526
- declare type PascalCase<S extends string> = string extends S ? string : Trim<DashDelim<LowerAllCaps<S>>> extends `${infer Begin}${Delimiter}${infer Rest}` ? PascalCase<`${Capitalize<Begin>}${Capitalize<Rest>}`> : Capitalize<Trim<LowerAllCaps<S>>>;
1527
-
1528
- declare type CamelCase<S extends string> = string extends S ? string : Uncapitalize<PascalCase<S>>;
1529
-
1530
- /**
1531
- * Capitalize all words in a string
1532
- */
1533
- declare type CapitalizeWords<S extends string> = S extends `${infer L} ${infer R}` ? `${CapitalizeWords<L>} ${CapitalizeWords<R>}` : S extends `${infer L},${infer R}` ? `${CapitalizeWords<L>},${CapitalizeWords<R>}` : S extends `${infer L}.${infer R}` ? `${CapitalizeWords<L>}.${CapitalizeWords<R>}` : Capitalize<S>;
1534
-
1535
- declare type DashToSnake<T extends string> = T extends `${infer HEAD}-${infer TAIL}` ? DashToSnake<`${HEAD}_${TAIL}`> : T;
1536
-
1537
- /**
1538
- * Indicates whether `T` has uppercase characters in it.
1539
- * ```ts
1540
- * // true
1541
- * type T = HasUppercase<"Foobar">;
1542
- * // false
1543
- * type T = HasUppercase<"foobar">;
1544
- * // "unknown"
1545
- * type T = HasUppercase<string>;
1546
- * ```
1547
- */
1548
- declare type HasUppercase<T extends string> = string extends T ? "unknown" : T extends `${string}${UpperAlpha}${string}` ? true : false;
1549
-
1550
- declare type _DU<T extends string> = T extends Lowercase<T> ? T : `-${Lowercase<T>}`;
1551
- /**
1552
- * Converts uppercase characters to a dash and then the lowercase equivalent
1553
- * ```ts
1554
- * // "one-two-three"
1555
- * type T = DashUppercase<"oneTwoThree">;
1556
- * ```
1402
+ * A mapping function between an input type `I` and output type `O`. Defaults to using
1403
+ * the _default_ OneToMany mapping config.
1557
1404
  *
1558
- * _Intended to be used as a lower level utility; prefer `Dasherize<T>` for more full-fledged
1559
- * dash solution_.
1405
+ * **Note:** this type is designed to guide the userland mapping; refer
1406
+ * to `MapFn` if you want the type output by the `mapFn()` utility.
1560
1407
  */
1561
- declare type DashUppercase<T extends string> = HasUppercase<T> extends false ? T : T extends `${infer C0}${infer C1}${infer R}` ? `${_DU<C0>}${_DU<C1>}${DashUppercase<R>}` : T extends `${infer C0}${infer R}` ? `${_DU<C0>}${DashUppercase<R>}` : "";
1562
-
1563
- declare type OneToOne = `1:1`;
1564
- declare type OneToMany = `1:M`;
1565
- declare type OneToZero = `1:0`;
1566
- declare type ZeroToOne = `0:1`;
1567
- declare type ZeroToMany = `0:M`;
1568
- declare type ZeroToZero = `0:0`;
1569
- declare type ManyToMany = "M:M";
1570
- declare type ManyToOne = "M:1";
1571
- declare type ManyToZero = "M:0";
1572
- declare type CardinalityNode = "0" | "1" | "M";
1408
+ type MapTo<I, O, C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired> = DefaultOneToManyMapping> = MapIR<C> extends "opt" ? (source?: MapInput<I, MapIR<C>, MapCard<C>>) => MapOutput<O, MapOR<C>, MapCard<C>> : (source: MapInput<I, MapIR<C>, MapCard<C>>) => MapOutput<O, MapOR<C>, MapCard<C>>;
1409
+ type MapFnOutput<I, O, S, OR extends OptRequired, C extends MapCardinalityIllustrated> = C extends "I -> O[]" | MapCardinality.OneToMany ? S extends I[] ? OR extends "opt" ? O[] : [O, ...O[]] : OR extends "opt" ? O[] | null : O[] : C extends MapCardinality.OneToOne | "I -> O" ? S extends I[] ? OR extends "opt" ? O[] : [O, ...O[]] : OR extends "opt" ? O | null : O : C extends MapCardinality.ManyToOne | "I[] -> O" ? S extends I[][] ? OR extends "opt" ? O[] : [O, ...O[]] : OR extends "opt" ? O | null : O : never;
1410
+ type MapFnInput<I, IR extends OptRequired, D extends MapCardinalityIllustrated> = D extends "I -> O[]" | MapCardinality.OneToMany ? IR extends "opt" ? I | I[] | undefined : I | I[] : D extends MapCardinality.OneToOne | "I -> O" ? IR extends "opt" ? I | I[] | undefined : I | I[] : D extends MapCardinality.ManyToOne | "I[] -> O" ? IR extends "opt" ? I[] | I[][] | undefined : I[] | I[][] : never;
1573
1411
  /**
1574
- * Cardinality which expects a singular input and requires
1575
- * 1 or many outputs.
1412
+ * The mapping function provided by the `mapFn()` utility. This _fn_
1413
+ * is intended to be used in two ways:
1576
1414
  *
1577
- * Note: choose `CardinalityFilter1` if you want to allow output
1578
- * to have no outputs.
1579
- */
1580
- declare type Cardinality1 = OneToOne | OneToMany;
1581
- /**
1582
- * Cardinality which expects a singular input and maps to 0,
1583
- * 1, or many outputs.
1584
- */
1585
- declare type CardinalityFilter1 = OneToOne | OneToMany | OneToZero;
1586
- /**
1587
- * Cardinality which expects a singular input which is allowed to be
1588
- * _undefined_ or the expected type.
1589
- */
1590
- declare type Cardinality0 = ZeroToOne | ZeroToMany | OneToOne | OneToMany;
1591
- /**
1592
- * Cardinality which expects a singular input -- which is allowed to be
1593
- * _undefined_ -- and maps to 0,
1594
- * 1, or many outputs.
1595
- */
1596
- declare type CardinalityFilter0 = ZeroToOne | ZeroToMany | OneToOne | OneToMany | OneToZero | ZeroToZero;
1597
- declare type CardinalityExplicit = `${number}:${number}`;
1598
- /**
1599
- * Cardinality of any sort between two types
1600
- */
1601
- declare type Cardinality = CardinalityFilter0 | CardinalityFilter1 | ManyToMany | ManyToOne | ManyToZero | CardinalityExplicit;
1602
- declare type CardinalityTuple<T extends Cardinality> = UnionToTuple<T>;
1603
- /**
1604
- * The first or _input_ part of the Cardinality relationship
1605
- */
1606
- declare type CardinalityIn<T extends Cardinality> = T extends `${infer IN}:${string}` ? IN : never;
1607
- /**
1608
- * The second or _output_ part of the Cardinality relationship
1415
+ * 1. Iterative:
1416
+ * ```ts
1417
+ * const m = mapTo<I,O>(i => [ ... ]);
1418
+ * // maps inputs to outputs
1419
+ * const out = inputs.map(m);
1420
+ * ```
1421
+ * 2. Block:
1422
+ * ```ts
1423
+ * // maps inputs to outputs (filtering or splitting where appr.)
1424
+ * const out2 = m(inputs);
1425
+ * ```
1609
1426
  */
1610
- declare type CardinalityOut<T extends Cardinality> = T extends `${string}:${infer OUT}` ? OUT : never;
1611
- declare type CardinalityInput<T, C extends Cardinality> = CardinalityTuple<C>[0] extends 0 ? T | undefined : CardinalityTuple<C>[0] extends 1 ? T : T[];
1612
-
1427
+ type MapFn<I, O, C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = MapIR<C> extends "opt" ? <S extends MapFnInput<I, MapIR<C>, MapCard<C>>>(source?: S) => MapFnOutput<I, O, S, MapOR<C>, MapCard<C>> : <S extends MapFnInput<I, MapIR<C>, MapCard<C>>>(source: S) => MapFnOutput<I, O, S, MapOR<C>, MapCard<C>>;
1613
1428
  /**
1614
- * Converts a string literal into a _dasherized_ format while ignoring _exterior_ whitespace.
1429
+ * **Mapper**
1615
1430
  *
1431
+ * A fully configured _mapper_ stemming from the **mapTo()** utility. It is both a mapping
1432
+ * function and a dictionary which describes the mapper's properties.
1616
1433
  * ```ts
1617
- * // "foo-bar"
1618
- * type Dash = Dasherize<"foo_bar">;
1619
- * type Dash = Dasherize<"fooBar">;
1620
- * type Dash = Dasherize<"FooBar">;
1621
- * // "\n foo-bar \t"
1622
- * type Dash = Dasherize<"\n foo bar \t">;
1623
- * ```
1624
- */
1625
- declare type Dasherize<S extends string> = string extends S ? string : DashUppercase<Trim<LowerAllCaps<S>>> extends `${infer Begin}${"_" | " "}${infer Rest}` ? Dasherize<`${Lowercase<Begin>}-${Rest}`> : Lowercase<DashUppercase<Uncapitalize<Trim<LowerAllCaps<S>>>>>;
1626
-
1627
- /**
1628
- * Returns true or false value based on whether the string literal is capitalized.
1629
- * ```ts
1630
- * // true
1631
- * type T2 = IsCapitalized<"One">;
1632
- * // false
1633
- * type T1 = IsCapitalized<"one">;
1634
- * // "unknown"
1635
- * const a: string = "Hi";
1636
- * type T3 = IsCapitalized<typeof a>;
1434
+ * const m = mapTo.oneToOne().map( ... );
1435
+ * const mapped = m(inputs);
1436
+ * const mappedOver = inputs.map(m);
1637
1437
  * ```
1638
1438
  *
1639
- * Note: _if the value passed in is a "string" then the result will be "unknown"_
1439
+ * Note: the root of a `Mapper` is the mapper function but
1440
+ * this is combined with a dictionary of settings and types
1441
+ * which you can use. For instance, look at the `fnSignature`
1442
+ * property to get the _type_ signature of the map function.
1640
1443
  */
1641
- declare type IsCapitalized<T extends string> = string extends T ? "unknown" : T extends Capitalize<T> ? true : false;
1642
-
1643
- /**
1644
- * **KebabCase<T>** is an _alias_ for **Dasherize<T>**.
1645
- * ```ts
1646
- * // "foo-bar"
1647
- * type Kebab = KebabCase<"foo_bar">;
1648
- * type Kebab = KebabCase<"fooBar">;
1649
- * type Kebab = KebabCase<"FooBar">;
1650
- * // "\n foo-bar \t"
1651
- * type Kebab = KebabCase<"\n foo bar \t">;
1652
- * ``` */
1653
- declare type KebabCase<T extends string> = Dasherize<T>;
1654
-
1655
- declare type Consonant = "b" | "c" | "d" | "f" | "g" | "h" | "j" | "k" | "l" | "m" | "n" | "p" | "q" | "r" | "s" | "t" | "v" | "w" | "x" | "z" | "y";
1656
- declare type Exceptions = "photo => photos" | "piano => pianos" | "halo => halos" | "foot => feet" | "man => men" | "woman => women" | "person => people" | "mouse => mice" | "series => series" | "sheep => sheep" | "money => monies" | "deer => deer";
1657
- declare type SingularException<T = Exceptions> = T extends `${infer SINGULAR} => ${infer PLURAL}` ? SINGULAR : never;
1658
- declare type PluralException<T extends SingularException, E extends Exceptions = Exceptions> = E extends `${T} => ${infer PLURAL}` ? PLURAL : never;
1659
- declare type SingularNoun = "s" | "sh" | "ch" | "x" | "z" | "o";
1660
- declare type F = "f" | "fe";
1661
- declare type Y = `${Consonant}y`;
1662
- declare type RemoveTrailingY<T> = T extends `${infer HEAD}y` ? HEAD : T;
1663
- /** validates that a word ends with a pluralization exception */
1664
- declare type isException<T extends string> = T extends SingularException ? T : never;
1665
- /** validates that a string literal ends in "is" */
1666
- declare type EndsIn_IS<T extends string> = T extends `${infer HEAD}is` ? T : never;
1667
- /** validates that a string literal is a singular noun */
1668
- declare type EndsInSingularNoun<T extends string> = T extends `${infer HEAD}${SingularNoun}` ? T : never;
1669
- /** validates that a string literal ends in "f" or "fe" */
1670
- declare type EndsIn_F<T extends string> = T extends `${infer HEAD}${F}` ? T : never;
1671
- /** validates that a string literal ends a consonant followed by "y" */
1672
- declare type EndsIn_Y<T extends string> = T extends `${infer HEAD}${Y}` ? T : never;
1444
+ type Mapper<I = unknown, O = unknown, C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired> = FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = {
1445
+ input: MapIR<C>;
1446
+ output: MapOR<C>;
1447
+ cardinality: MapCard<C>;
1448
+ debug: boolean | string;
1449
+ inputType: I;
1450
+ outputType: O;
1451
+ /**
1452
+ * Provides the _type_ information for mapper function.
1453
+ *
1454
+ * Note: _this is just a **type**_ not the actual function which positioned
1455
+ * at the root of the Mapper type
1456
+ */
1457
+ fnSignature: MapFn<I, O, C>;
1458
+ } & MapFn<I, O, C>;
1673
1459
  /**
1674
- * strings which end in the letters "is" should have an "es" added to the end
1460
+ * **MapInputFrom**
1461
+ *
1462
+ * Type utility which extracts the `I` type from a fully configured `Mapper`
1675
1463
  */
1676
- declare type PluralizeEndingIn_IS<T extends string> = T extends `${infer HEAD}is` ? `${HEAD}ises` : T;
1464
+ type MapInputFrom<T extends Mapper> = T extends Mapper<infer I> ? I : never;
1677
1465
  /**
1678
- * singular nouns should have "es" added to the end
1466
+ * **MapOutputFrom**
1467
+ *
1468
+ * Type utility which extracts the output [`O`] type from a fully configured `Mapper`
1679
1469
  */
1680
- declare type PluralizeEndingSingularNoun<T extends string> = T extends `${infer HEAD}${SingularNoun}` ? `${T}es` : T;
1470
+ type MapOutputFrom<T extends Mapper> = T extends Mapper<any, infer O> ? O : never;
1681
1471
  /**
1682
- * strings which end in the letters "f" or "fe" should have "ves" replace the ending
1472
+ * **MapCardinalityFrom**
1473
+ *
1474
+ * Type utility which extracts _cardinality_ of a `Mapper`'s inputs to outputs
1683
1475
  */
1684
- declare type PluralizeEnding_F<T extends string> = T extends `${infer HEAD}${F}` ? `${HEAD}ves` : T;
1476
+ type MapCardinalityFrom<T extends Mapper> = T extends Mapper<any, any, infer C> ? C extends FinalizedMapConfig<OptRequired, infer Cardinality, OptRequired> ? Cardinality : never : never;
1477
+
1685
1478
  /**
1686
- * singular nouns should have "es" added to the end
1479
+ * Given a dictionary of type `<T>`, this utility function will
1480
+ * make the `<M>` generic property _mutable_ and all other _read-only_.
1481
+ *
1482
+ * ```ts
1483
+ * // { foo: string, bar?: Readonly<number> }
1484
+ * type Example = MutableProps<{
1485
+ * foo: Readonly<string>,
1486
+ * bar?: number
1487
+ * }, "foo">;
1488
+ * ```
1687
1489
  */
1688
- declare type PluralizeEndingIn_Y<T extends string> = T extends `${infer HEAD}${Y}` ? `${RemoveTrailingY<T>}ies` : T;
1689
- declare type Pluralize<T extends string> = T extends isException<T> ? PluralException<T> : T extends EndsIn_IS<T> ? PluralizeEndingIn_IS<T> : T extends EndsInSingularNoun<T> ? PluralizeEndingSingularNoun<T> : T extends EndsIn_F<T> ? PluralizeEnding_F<T> : T extends EndsIn_Y<T> ? PluralizeEndingIn_Y<T> : `${T}s`;
1490
+ type MutableProps<T extends {}, M extends keyof T & string> = ExpandRecursively<Mutable<Pick<T, M>> & Readonly<Pick<T, Keys<T, M>>>>;
1690
1491
 
1691
- /** convert space to dash */
1692
- declare type SpaceToDash<T extends string> = T extends `${infer Begin}${" "}${infer Rest}` ? SpaceToDash<`${Begin}-${Rest}`> : T;
1693
1492
  /**
1694
- * Converts a string literal type to _snake_case_.
1493
+ * Given a dictionary of type `<T>`, this utility function will
1494
+ * make the `<R>` generic property _required_ (use a union to make
1495
+ * more than one prop required).
1496
+ *
1695
1497
  * ```ts
1696
- * // "foo_bar"
1697
- * type T = SnakeCase<"fooBar">;
1698
- * type T = SnakeCase<"FooBar">;
1699
- * type T = SnakeCase<"foo-bar">;
1700
- * type T = SnakeCase<"\n foo bar \t">;
1701
- * ``` */
1702
- declare type SnakeCase<S extends string> = string extends S ? string : DashUppercase<Uncapitalize<SpaceToDash<Trim<LowerAllCaps<S>>>>> extends `${infer Begin}${"-"}${infer Rest}` ? SnakeCase<`${Lowercase<Begin>}_${Rest}`> : Lowercase<DashUppercase<Uncapitalize<Trim<LowerAllCaps<S>>>>>;
1498
+ * // { foo: string, bar?: number }
1499
+ * type Example = RequireProps<{foo?: string, bar?: number}, "foo">;
1500
+ * ```
1501
+ */
1502
+ type RequireProps<T extends {}, R extends keyof T> = ExpandRecursively<Required<Pick<T, R>> & T>;
1703
1503
 
1704
1504
  /**
1705
1505
  * **ToFluent**
@@ -1710,7 +1510,7 @@ declare type SnakeCase<S extends string> = string extends S ? string : DashUpper
1710
1510
  * **Note:** this utility also allows a non-fluent API surface `X` to be included as
1711
1511
  * part of the API surface if this is desired.
1712
1512
  */
1713
- declare type ToFluent<T extends {
1513
+ type ToFluent<T extends {
1714
1514
  [key: string]: (...args: any[]) => any;
1715
1515
  }, X extends object = {}> = {
1716
1516
  [K in keyof T]: (...args: Parameters<T[K]>) => ToFluent<T, X> & X;
@@ -1726,7 +1526,7 @@ declare type ToFluent<T extends {
1726
1526
  * **Note:** _if you prefer a Fluent API with means to _escape_ with an internally managed state then
1727
1527
  * you should prefer the use of the `FluentApi` type._
1728
1528
  */
1729
- declare type PureFluentApi<TApi extends Record<string, (...args: any[]) => PureFluentApi<TApi, any>>, TExclude extends string = ""> = {
1529
+ type PureFluentApi<TApi extends Record<string, (...args: any[]) => PureFluentApi<TApi, any>>, TExclude extends string = ""> = {
1730
1530
  [P in keyof TApi]: (...args: Parameters<TApi[P]>) => PureFluentApi<Omit<TApi, TExclude>>;
1731
1531
  };
1732
1532
 
@@ -1739,14 +1539,14 @@ declare type PureFluentApi<TApi extends Record<string, (...args: any[]) => PureF
1739
1539
  * type T = FinalReturn<() => (foo: string) => (bar: string) => () => number>;
1740
1540
  * ```
1741
1541
  */
1742
- declare type FinalReturn<T extends any> = T extends (...args: any[]) => any ? FinalReturn<ReturnType<T>> : T;
1542
+ type FinalReturn<T extends any> = T extends (...args: any[]) => any ? FinalReturn<ReturnType<T>> : T;
1743
1543
 
1744
1544
  /**
1745
1545
  * A function which returns a boolean value
1746
1546
  */
1747
- declare type LogicFunction<T extends any[]> = (...args: T) => boolean;
1547
+ type LogicFunction<T extends any[]> = (...args: T) => boolean;
1748
1548
 
1749
- declare type DictFromKv<T extends readonly {
1549
+ type DictFromKv<T extends readonly {
1750
1550
  key: string;
1751
1551
  value: unknown;
1752
1552
  }[]> = {
@@ -1762,7 +1562,7 @@ declare type DictFromKv<T extends readonly {
1762
1562
  * type Foo = KeyValue<Obj, "foo">;
1763
1563
  * ```
1764
1564
  */
1765
- declare type KeyValue<T extends object, K extends keyof T> = [K & keyof T, ExpandRecursively<T[K]>];
1565
+ type KeyValue<T extends object, K extends keyof T> = [K & keyof T, ExpandRecursively<T[K]>];
1766
1566
 
1767
1567
  /**
1768
1568
  * Type utility which takes an object type and converts to an array of KV objects:
@@ -1771,7 +1571,7 @@ declare type KeyValue<T extends object, K extends keyof T> = [K & keyof T, Expan
1771
1571
  * type Arr = KvFrom<{ id: 123, foo: "bar" }>;
1772
1572
  * ```
1773
1573
  */
1774
- declare type KvFrom<T extends object> = Array<{
1574
+ type KvFrom<T extends object> = Array<{
1775
1575
  [K in keyof T]: {
1776
1576
  key: K;
1777
1577
  value: T[K];
@@ -1791,7 +1591,27 @@ declare type KvFrom<T extends object> = Array<{
1791
1591
  *
1792
1592
  * **Note:** _consider use of `KeyValue<T,K>` as an alternate representation_
1793
1593
  */
1794
- declare type KvTuple<T, K extends keyof T> = [K, Record<K, T[K]>];
1594
+ type KvTuple<T, K extends keyof T> = [K, Record<K, T[K]>];
1595
+
1596
+ /**
1597
+ * **AfterFirst**`<T>`
1598
+ *
1599
+ * returns the elements in an array _after_ the first element
1600
+ */
1601
+ type AfterFirst<T extends readonly any[]> = T extends readonly [any, ...any[]] ? T extends readonly [any, ...infer Rest] ? Rest : never : T;
1602
+
1603
+ /**
1604
+ * returns the first `string` value from an array of values
1605
+ */
1606
+ type FirstString<T> = T extends [infer S extends string, ...unknown[]] ? S : never;
1607
+
1608
+ /**
1609
+ * **Split**`<T, SEP>`
1610
+ *
1611
+ * Splits a string literal `T` by string literal _separator_ `SEP`. The result is an array
1612
+ * of string literals.
1613
+ */
1614
+ type Split<T extends string, SEP extends string, ANSWER extends string[] = []> = string extends T ? string[] : T extends SEP ? ANSWER : T extends `${infer HEAD}${SEP}${infer TAIL}` ? Split<TAIL, SEP, [...ANSWER, HEAD]> : [...ANSWER, T];
1795
1615
 
1796
1616
  /**
1797
1617
  * Create a union type based on a given property in an array of objects
@@ -1804,14 +1624,14 @@ declare type KvTuple<T, K extends keyof T> = [K, Record<K, T[K]>];
1804
1624
  * type U = UniqueForProp<typeof data, "id">;
1805
1625
  * ```
1806
1626
  */
1807
- declare type UniqueForProp<T extends readonly Record<string, Narrowable>[], P extends string> = Readonly<Get<T[number], P>>;
1627
+ type UniqueForProp<T extends readonly Record<string, Narrowable>[], P extends string> = Readonly<Get<T[number], P>>;
1808
1628
 
1809
- declare type DictArrayFilterCallback<K extends keyof T, T extends object, R extends true | false> = (key: K, value: Pick<T, K>) => R;
1629
+ type DictArrayFilterCallback<K extends keyof T, T extends object, R extends true | false> = (key: K, value: Pick<T, K>) => R;
1810
1630
  /**
1811
1631
  * An element in a `DictArray` shaped as a two element tuple: `[key, kv]`.
1812
1632
  */
1813
- declare type DictArrayKv<K extends keyof T, T> = [K, Pick<T, K>];
1814
- declare type DictKvTuple<K extends string> = [K, Record<K, unknown>];
1633
+ type DictArrayKv<K extends keyof T, T> = [K, Pick<T, K>];
1634
+ type DictKvTuple<K extends string> = [K, Record<K, unknown>];
1815
1635
  /**
1816
1636
  * A an array of `DictArrayKv` tuples which can be reconstructed
1817
1637
  * to a strongly typed dictionary object.
@@ -1822,7 +1642,7 @@ declare type DictKvTuple<K extends string> = [K, Record<K, unknown>];
1822
1642
  * ]
1823
1643
  * ```
1824
1644
  */
1825
- declare type DictArray<T> = Array<{
1645
+ type DictArray<T> = Array<{
1826
1646
  [K in keyof T]: DictArrayKv<K, T>;
1827
1647
  }[keyof T]>;
1828
1648
 
@@ -1832,7 +1652,7 @@ declare type DictArray<T> = Array<{
1832
1652
  * **Note:** key order is not guarenteed so typically this is used
1833
1653
  * for a key/value pair where only one key is expected
1834
1654
  */
1835
- declare type FirstKey<T extends object> = UnionToTuple<Keys<T>>[0];
1655
+ type FirstKey<T extends object> = UnionToTuple<Keys<T>>[0];
1836
1656
 
1837
1657
  /**
1838
1658
  * Utility type which operates on a dictionary and provides the **value** of the
@@ -1840,7 +1660,7 @@ declare type FirstKey<T extends object> = UnionToTuple<Keys<T>>[0];
1840
1660
  * about key order, this is typically only used in cases where it's known there is
1841
1661
  * a single key on the object.
1842
1662
  */
1843
- declare type FirstKeyValue<T extends object> = FirstKey<T> extends keyof T ? T[FirstKey<T>] : never;
1663
+ type FirstKeyValue<T extends object> = FirstKey<T> extends keyof T ? T[FirstKey<T>] : never;
1844
1664
 
1845
1665
  /**
1846
1666
  * For a two-dimensional array, returns a _union type_ which combines the first element of the interior
@@ -1852,7 +1672,7 @@ declare type FirstKeyValue<T extends object> = FirstKey<T> extends keyof T ? T[F
1852
1672
  * type F = FirstOfEach<typeof test>;
1853
1673
  * ```
1854
1674
  */
1855
- declare type FirstOfEach<T extends readonly any[][]> = T[number][0] extends T[number][number] ? T[number][0] : never;
1675
+ type FirstOfEach<T extends readonly any[][]> = T[number][0] extends T[number][number] ? T[number][0] : never;
1856
1676
 
1857
1677
  /**
1858
1678
  * Typescript utility which receives `T` as shape which resembles `DictArray<D>`
@@ -1862,7 +1682,7 @@ declare type FirstOfEach<T extends readonly any[][]> = T[number][0] extends T[nu
1862
1682
  * type Dict = FromDictArray<[["foo", { foo: 1 }], ["bar", { bar: "hi" }]]>;
1863
1683
  * ```
1864
1684
  */
1865
- declare type FromDictArray<T extends [string, Record<string, unknown>][]> = ExpandRecursively<UnionToIntersection<T[number][1]>>;
1685
+ type FromDictArray<T extends [string, Record<string, unknown>][]> = ExpandRecursively<UnionToIntersection<T[number][1]>>;
1866
1686
 
1867
1687
  /**
1868
1688
  * For a two-dimensional array, returns a _union type_ which combines the first element of the interior
@@ -1873,7 +1693,7 @@ declare type FromDictArray<T extends [string, Record<string, unknown>][]> = Expa
1873
1693
  * type F = SecondOfEach<[ ["foo", 1], ["bar", 2] ]>;
1874
1694
  * ```
1875
1695
  */
1876
- declare type SecondOfEach<T extends any[][]> = T[number][1] extends T[number][number] ? T[number][1] : never;
1696
+ type SecondOfEach<T extends any[][]> = T[number][1] extends T[number][number] ? T[number][1] : never;
1877
1697
 
1878
1698
  declare function createFnWithProps<F extends Function, P extends {}>(fn: F, props: P): F & P;
1879
1699
  /**
@@ -1934,41 +1754,41 @@ declare const or: <T extends any[]>(...ops: LogicFunction<T>[]) => LogicFunction
1934
1754
  */
1935
1755
  declare const not: <T extends any[]>(op: LogicFunction<T>) => LogicFunction<T>;
1936
1756
 
1937
- declare type FilterStarts = {
1757
+ type FilterStarts = {
1938
1758
  /** one or more string which the value is allowed to start with */
1939
1759
  startsWith: string | string[];
1940
1760
  };
1941
- declare type FilterIs = {
1761
+ type FilterIs = {
1942
1762
  /** whether a string _**is**_ of a particular value */
1943
1763
  is: string | string[];
1944
1764
  };
1945
- declare type FilterEnds = {
1765
+ type FilterEnds = {
1946
1766
  endsWith: string | string[];
1947
1767
  };
1948
- declare type FilterContains = {
1768
+ type FilterContains = {
1949
1769
  /** whether any of the strings specified are _contained_ in the value */
1950
1770
  contains: string | string[];
1951
1771
  };
1952
- declare type FilterEquals = {
1772
+ type FilterEquals = {
1953
1773
  /** one or more values which _equal_ the value passed in */
1954
1774
  equals: number | number[];
1955
1775
  };
1956
- declare type FilterNotEqual = {
1776
+ type FilterNotEqual = {
1957
1777
  /** one or more values which ALL _do not equal_ the value passed in */
1958
1778
  notEqual: number | number[];
1959
1779
  };
1960
- declare type FilterGreaterThan = {
1780
+ type FilterGreaterThan = {
1961
1781
  /** the incoming value is greater than this value */
1962
1782
  greaterThan: number;
1963
1783
  };
1964
- declare type FilterLessThan = {
1784
+ type FilterLessThan = {
1965
1785
  /** the incoming value is less than this value */
1966
1786
  lessThan: number;
1967
1787
  };
1968
- declare type StringFilter = FilterIs | FilterStarts | FilterEnds | FilterContains | (FilterStarts & FilterEnds) | (FilterStarts & FilterContains) | (FilterEnds & FilterContains) | (FilterStarts & FilterEnds & FilterContains);
1969
- declare type NumericFilter = FilterEquals | FilterNotEqual | FilterGreaterThan | FilterLessThan | (FilterEquals & FilterNotEqual) | (FilterEquals & FilterGreaterThan) | (FilterEquals & FilterLessThan) | (FilterNotEqual & FilterGreaterThan) | (FilterNotEqual & FilterLessThan) | (FilterGreaterThan & FilterLessThan) | (FilterEquals & FilterGreaterThan & FilterLessThan) | (FilterNotEqual & FilterGreaterThan & FilterLessThan) | (FilterEquals & FilterNotEqual & FilterGreaterThan & FilterLessThan);
1970
- declare type FilterDefn = StringFilter | NumericFilter;
1971
- declare type NotFilter = {
1788
+ type StringFilter = FilterIs | FilterStarts | FilterEnds | FilterContains | (FilterStarts & FilterEnds) | (FilterStarts & FilterContains) | (FilterEnds & FilterContains) | (FilterStarts & FilterEnds & FilterContains);
1789
+ type NumericFilter = FilterEquals | FilterNotEqual | FilterGreaterThan | FilterLessThan | (FilterEquals & FilterNotEqual) | (FilterEquals & FilterGreaterThan) | (FilterEquals & FilterLessThan) | (FilterNotEqual & FilterGreaterThan) | (FilterNotEqual & FilterLessThan) | (FilterGreaterThan & FilterLessThan) | (FilterEquals & FilterGreaterThan & FilterLessThan) | (FilterNotEqual & FilterGreaterThan & FilterLessThan) | (FilterEquals & FilterNotEqual & FilterGreaterThan & FilterLessThan);
1790
+ type FilterDefn = StringFilter | NumericFilter;
1791
+ type NotFilter = {
1972
1792
  /**
1973
1793
  * **not**
1974
1794
  *
@@ -1978,11 +1798,11 @@ declare type NotFilter = {
1978
1798
  not: FilterDefn;
1979
1799
  };
1980
1800
  declare function isNotFilter(f: FilterDefn | NotFilter): f is NotFilter;
1981
- declare type UnwrapNot<T extends FilterDefn | NotFilter> = T extends NotFilter ? T["not"] extends StringFilter ? StringFilter : NumericFilter : T;
1801
+ type UnwrapNot<T extends FilterDefn | NotFilter> = T extends NotFilter ? T["not"] extends StringFilter ? StringFilter : NumericFilter : T;
1982
1802
  declare function isNumericFilter(filter: FilterDefn): filter is NumericFilter;
1983
- declare type UndefinedValue<U extends boolean> = true extends U ? "undefined treated as 'true'" : U extends "no-impact" ? "undefined treated in no-impact fashion" : "undefined treated as 'false'";
1984
- declare type UndefinedTreatment = "undefined treated as 'true'" | "undefined treated as 'false'";
1985
- declare type LogicalCombinator = "AND" | "OR";
1803
+ type UndefinedValue<U extends boolean> = true extends U ? "undefined treated as 'true'" : U extends "no-impact" ? "undefined treated in no-impact fashion" : "undefined treated as 'false'";
1804
+ type UndefinedTreatment = "undefined treated as 'true'" | "undefined treated as 'false'";
1805
+ type LogicalCombinator = "AND" | "OR";
1986
1806
  /**
1987
1807
  * **FilterFn**
1988
1808
  *
@@ -1994,11 +1814,11 @@ declare type LogicalCombinator = "AND" | "OR";
1994
1814
  * ```
1995
1815
  *
1996
1816
  */
1997
- declare type FilterFn<T extends StringFilter | NumericFilter> = T extends StringFilter ? <V extends string | undefined>(input: V) => boolean : <V extends number | undefined>(input: V) => boolean;
1817
+ type FilterFn<T extends StringFilter | NumericFilter> = T extends StringFilter ? <V extends string | undefined>(input: V) => boolean : <V extends number | undefined>(input: V) => boolean;
1998
1818
  /**
1999
1819
  * Defines a logical function for each condition type
2000
1820
  */
2001
- declare type ConditionFilter<T extends StringFilter | NumericFilter> = T extends StringFilter ? (input: string) => boolean : (input: number) => boolean;
1821
+ type ConditionFilter<T extends StringFilter | NumericFilter> = T extends StringFilter ? (input: string) => boolean : (input: number) => boolean;
2002
1822
  /**
2003
1823
  * **filter**
2004
1824
  *
@@ -2064,7 +1884,7 @@ interface Uniqueness<T> {
2064
1884
  /** the unique values for the property across all records */
2065
1885
  values: readonly T[];
2066
1886
  }
2067
- declare type DictArrApi<T extends Record<string, Narrowable>, A extends readonly T[]> = {
1887
+ type DictArrApi<T extends Record<string, Narrowable>, A extends readonly T[]> = {
2068
1888
  length: number;
2069
1889
  toLookup<PL extends RequiredKeys<T, string> & keyof T & string>(prop: PL): UniqueForProp<A, PL> extends string ? Record<UniqueForProp<A, PL>, T> : Record<string, T>;
2070
1890
  sum<PS extends RequiredKeys<T, number> | OptionalKeys<T, number>>(prop: PS): number;
@@ -2166,8 +1986,8 @@ declare function kvToDict<K extends string, V extends Narrowable, T extends read
2166
1986
  /**
2167
1987
  * Type utility which converts `undefined[]` to `unknown[]`
2168
1988
  */
2169
- declare type UndefinedArrayIsUnknown<T extends any[]> = undefined[] extends T ? unknown[] : T;
2170
- declare type AsArray<T, W extends boolean = false> = T extends any[] ? W extends true ? Widen<T> : T : W extends true ? UndefinedArrayIsUnknown<Widen<T>[]> : UndefinedArrayIsUnknown<T[]>;
1989
+ type UndefinedArrayIsUnknown<T extends any[]> = undefined[] extends T ? unknown[] : T;
1990
+ type AsArray<T, W extends boolean = false> = T extends any[] ? W extends true ? Widen<T> : T : W extends true ? UndefinedArrayIsUnknown<Widen<T>[]> : UndefinedArrayIsUnknown<T[]>;
2171
1991
  /**
2172
1992
  * Ensures that any input passed in is passed back as an array:
2173
1993
  *
@@ -2193,7 +2013,7 @@ declare const asArray: <T extends Narrowable, W extends boolean = true>(thing: T
2193
2013
  */
2194
2014
  declare function groupBy<T extends Record<string, Narrowable>>(_data: Readonly<T[]>): void;
2195
2015
 
2196
- declare type ExplicitFunction<P extends any[], R extends any> = (...args: P) => R;
2016
+ type ExplicitFunction<P extends any[], R extends any> = (...args: P) => R;
2197
2017
  /**
2198
2018
  * Takes a given function and converts it to an explicit representation
2199
2019
  * where the generics represent the _parameter_ and _return_ typings.
@@ -2206,7 +2026,7 @@ declare function ExplicitFunction<T extends (...args: any[]) => any>(fn: T): Exp
2206
2026
  * A dictionary converted by `arrayToObject()` which expects each key `S` to have a only a
2207
2027
  * single/unique value.
2208
2028
  */
2209
- declare type UniqueDictionary<S extends PropertyKey, N extends Narrowable, T extends Record<keyof T, N> & Record<S, any>> = {
2029
+ type UniqueDictionary<S extends PropertyKey, N extends Narrowable, T extends Record<keyof T, N> & Record<S, any>> = {
2210
2030
  [V in T as V[S]]: V;
2211
2031
  };
2212
2032
  /**
@@ -2215,10 +2035,10 @@ declare type UniqueDictionary<S extends PropertyKey, N extends Narrowable, T ext
2215
2035
  * A dictionary converted by `arrayToObject()` which expects each key `S` to have an
2216
2036
  * array of values.
2217
2037
  */
2218
- declare type GeneralDictionary<S extends PropertyKey, N extends Narrowable, T extends Record<keyof T, N> & Record<S, any>> = {
2038
+ type GeneralDictionary<S extends PropertyKey, N extends Narrowable, T extends Record<keyof T, N> & Record<S, any>> = {
2219
2039
  [V in T as V[S]]: V[];
2220
2040
  };
2221
- declare type ArrayConverter<S extends PropertyKey, U extends boolean> =
2041
+ type ArrayConverter<S extends PropertyKey, U extends boolean> =
2222
2042
  /**
2223
2043
  * An `ArrayConverter` is the partial application of the `arrayToObject()`
2224
2044
  * utility. At this point, the configuration is setup already and all that's
@@ -2241,6 +2061,33 @@ declare type ArrayConverter<S extends PropertyKey, U extends boolean> =
2241
2061
  */
2242
2062
  declare function arrayToObject<S extends PropertyKey, U extends boolean>(prop: S, unique?: U): ArrayConverter<S, true extends U ? true : false>;
2243
2063
 
2064
+ interface Box<T> {
2065
+ __kind: "box";
2066
+ value: T;
2067
+ /**
2068
+ * Unbox the boxed value in the narrowest possible type.
2069
+ *
2070
+ * **Note:** _if you want a wider type definition use `wide()`
2071
+ * instead._
2072
+ */
2073
+ unbox(): T;
2074
+ }
2075
+ type BoxValue<T extends Box<any>> = T extends Box<infer V> ? V : never;
2076
+ type BoxedFnParams<T extends Box<any>> = T extends Box<infer V> ? V extends (...args: infer A) => any ? A : [] : [];
2077
+ type BoxedReturn<T extends Box<any>> = T extends Box<infer V> ? V extends Function ? ReturnType<T["value"]> : T["value"] : never;
2078
+ type NarrowBox<T> = <N extends BoxedFnParams<Box<T>> | First<BoxedFnParams<Box<T>>>>() => N extends BoxedFnParams<Box<T>> ? T extends (...args: any[]) => any ? (...args: N) => Box<T>["unbox"] : never : (first: N, ...rest: AfterFirst<BoxedFnParams<Box<T>>>) => BoxedReturn<Box<T>>;
2079
+ /**
2080
+ * Allows a value with an inner-type to be boxed into a dictionary
2081
+ * so that this type inference is preserved with the help of
2082
+ * [instantiation expressions](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#instantiation-expressions).
2083
+ *
2084
+ * NOTE: this feature is immature at best right now
2085
+ */
2086
+ declare function box<T extends Narrowable>(value: T): Box<T>;
2087
+ declare function isBox(thing: unknown): thing is Box<any>;
2088
+ type Unbox<T> = T extends Box<infer U> ? U : T;
2089
+ declare function unbox<T>(thing: T): Unbox<T>;
2090
+
2244
2091
  /**
2245
2092
  * Build a _type_ from two run-time dictionaries.
2246
2093
  *
@@ -2296,30 +2143,240 @@ declare function idTypeGuard<T extends {
2296
2143
  */
2297
2144
  declare function literal<N extends Narrowable, T extends Record<keyof T, N>>(obj: T): T;
2298
2145
 
2299
- declare function Model<N extends string, _R extends {} = {}, _O extends {} = {}>(name: N): {
2300
- required<P extends string>(_prop: P): {
2301
- required<P_1 extends string>(_prop: P_1): any;
2302
- optional<P_2 extends string>(_prop: P_2): any;
2303
- done(): {
2304
- __model__: N;
2305
- __kind__: "model";
2306
- };
2307
- };
2308
- optional<P_3 extends string>(_prop: P_3): {
2309
- required<P_1 extends string>(_prop: P_1): any;
2310
- optional<P_2 extends string>(_prop: P_2): any;
2311
- done(): {
2312
- __model__: N;
2313
- __kind__: "model";
2314
- };
2315
- };
2316
- done(): {
2317
- __model__: N;
2318
- __kind__: "model";
2319
- };
2146
+ /**
2147
+ * **Suggest**
2148
+ *
2149
+ * Type utility that helps to build a enumerated set
2150
+ * of string literals which _could_ be the value for
2151
+ * a string based property but _allows_ a string that
2152
+ * is not part of the suggestion to be typed in too.
2153
+ */
2154
+ type Suggest<T extends string> = T | (string & {});
2155
+ /**
2156
+ * **SuggestNumeric**`<T>`
2157
+ *
2158
+ * Type utility that helps to build a enumerated set
2159
+ * of numeric literals which _could_ be the value for
2160
+ * a number based property but _allows_ a number that
2161
+ * is not part of the suggestion to be typed in too.
2162
+ */
2163
+ type SuggestNumeric<T extends number> = T | (number & {});
2164
+
2165
+ type Condition<TInput extends Narrowable, TResult extends boolean> = (input: TInput) => TResult;
2166
+ declare const condition: <TInput extends Narrowable, C extends Condition<Narrowable, boolean>>(c: C, input: TInput) => boolean;
2167
+
2168
+ type IsArray<T> = T extends any[] ? true : false;
2169
+ declare function isArray<T>(i: T): IsArray<T>;
2170
+
2171
+ type IsBoolean<T> = T extends boolean ? true : false;
2172
+ /**
2173
+ * Runtime and type checks whether a variable is a boolean value.
2174
+ */
2175
+ declare function isBoolean<T extends any>(i: T): IsBoolean<T>;
2176
+ /**
2177
+ * **ifBoolean**
2178
+ *
2179
+ * Strongly type-aware conditional statement which checks whether a value is
2180
+ * a _boolean_ and returns one of two values (strongly typed) based on the evaluation
2181
+ * of this criteria.
2182
+ *
2183
+ * @param val the value being tested
2184
+ * @param ifVal the value (strongly typed) returned if val is _boolean_
2185
+ * @param elseVal the value (strongly typed) returned if val is NOT a _boolean
2186
+ */
2187
+ declare function ifBoolean<T, IF, ELSE>(val: T, ifVal: IF, elseVal: ELSE): IsBoolean<T> extends true ? IF : ELSE;
2188
+
2189
+ type IsFalse<T extends Narrowable> = IsBoolean<T> extends true ? T extends false ? true : true extends T ? false : unknown : false;
2190
+ declare function isFalse<T>(i: T): IsFalse<T>;
2191
+
2192
+ type IsFunction<T> = T extends FunctionType ? true : false;
2193
+ type HybridFunction<TProps extends {}> = (<TArgs extends any[]>(...args: TArgs) => any) & TProps;
2194
+ type SimpleFunction = <TArgs extends any[]>(...args: TArgs) => any;
2195
+ type AnyFunction<TProps extends {} | never = never> = TProps extends {} ? HybridFunction<TProps> : SimpleFunction;
2196
+ /**
2197
+ * Checks whether a passed in value is a function and ensures run-time and types
2198
+ * are consistent.
2199
+ * ```ts
2200
+ * // true
2201
+ * const yup = isFunction(() => "hello world");
2202
+ * ```
2203
+ *
2204
+ * Note: the runtime `typeof [variable]` will correctly say "function" when a function is
2205
+ * encountered but if that function also has object types defined then the type will be a big
2206
+ * and ugly union type. This function will give you a proper boolean value in both cases.
2207
+ */
2208
+ declare function isFunction<T>(input: T): IsFunction<T>;
2209
+
2210
+ type IsNull<T> = T extends null ? true : false;
2211
+ declare function isNull<T extends Narrowable>(i: T): T extends null ? true : false;
2212
+ /**
2213
+ * **ifNull**
2214
+ *
2215
+ * Strongly type-aware conditional statement which checks whether a value is
2216
+ * Null and returns one of two values (strongly typed) based on the evaluation
2217
+ * of this criteria.
2218
+ *
2219
+ * @param val the value being tested
2220
+ * @param ifVal the value (strongly typed) returned if val is `null`
2221
+ * @param elseVal the value (strongly typed) returned if val is NOT `null`
2222
+ */
2223
+ declare function ifNull<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IsNull<T> extends true ? IF : ELSE;
2224
+
2225
+ type IsNumber<T> = T extends number ? true : false;
2226
+ declare function isNumber<T>(i: T): T extends number ? true : false;
2227
+ /**
2228
+ * **ifNumber**
2229
+ *
2230
+ * Strongly type-aware conditional statement which checks whether a value is
2231
+ * a _number_ and returns one of two values (strongly typed) based on the evaluation
2232
+ * of this criteria.
2233
+ *
2234
+ * @param val the value being tested
2235
+ * @param ifVal the value (strongly typed) returned if val is number
2236
+ * @param elseVal the value (strongly typed) returned if val is NOT a number
2237
+ */
2238
+ declare function ifNumber<T, IF, ELSE>(val: T, ifVal: IF, elseVal: ELSE): IsNumber<T> extends true ? IF : ELSE;
2239
+
2240
+ type ObjectType = Not<Record<string, Narrowable>, FunctionType>;
2241
+ /**
2242
+ * Detects whether the passed in `v` is of type "object" where an object
2243
+ * is defined to be a string keyed dictionary style object. This means that
2244
+ * arrays are excluded, as well as functions which also have properties hanging
2245
+ * off of them.
2246
+ */
2247
+ declare function isObject<T extends unknown>(i: T): IsObject<T>;
2248
+
2249
+ /**
2250
+ * **IsString**
2251
+ *
2252
+ * Type utility which returns true/false based on whether `T` is a
2253
+ * string (wide or narrow).
2254
+ */
2255
+ type IsString<T> = T extends string ? true : false;
2256
+ /**
2257
+ * **IfString**
2258
+ *
2259
+ * Type utility which determines if `T` is a _string_ (wide or narrow) and
2260
+ * returns `IF` type if it is, otherwise returns the type `ELSE`.
2261
+ */
2262
+ type IfString<T extends Narrowable, //
2263
+ IF extends Narrowable, ELSE extends Narrowable> = IsString<T> extends true ? IF : ELSE;
2264
+
2265
+ /**
2266
+ * **isString**
2267
+ *
2268
+ * Returns true or false on whether the passed in parameter is a
2269
+ * string (either a wide string or a string literal).
2270
+ *
2271
+ * The boolean return is traceable by the type system as well as the
2272
+ * runtime system.
2273
+ */
2274
+ declare function isString<T>(i: T): IsString<T>;
2275
+ /**
2276
+ * **ifString**
2277
+ *
2278
+ * Strongly type-aware conditional statement which checks whether a value is
2279
+ * a _string_ and returns one of two values (strongly typed) based on the evaluation
2280
+ * of this criteria.
2281
+ *
2282
+ * @param val the value being tested for being a string
2283
+ * @param ifVal the value (strongly typed) returned if val is _string_
2284
+ * @param elseVal the value (strongly typed) returned if val is NOT a _string
2285
+ */
2286
+ declare function ifString<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IfString<T, IF, ELSE>;
2287
+
2288
+ declare function isSymbol<T>(i: T): T extends symbol ? true : false;
2289
+
2290
+ /**
2291
+ * Type utility which returns `true` or `false` based on
2292
+ * whether the type holds the narrow "true" type.
2293
+ * ```ts
2294
+ * // true
2295
+ * type T = IsTrue<true>;
2296
+ * // unknown
2297
+ * type U = IsTrue<boolean>;
2298
+ * // false
2299
+ * type F = IsTrue<false>;
2300
+ * type F2 = IsTrue<"false">;
2301
+ * ```
2302
+ */
2303
+ type IsTrue<T> = IsBoolean<T> extends true ? T extends true ? true : T extends false ? false : unknown : false;
2304
+ /**
2305
+ * Run-time and type checking of whether a variable is `true`.
2306
+ */
2307
+ declare function isTrue<T extends Narrowable>(i: T): IsTrue<T>;
2308
+ /**
2309
+ * **ifTrue**
2310
+ *
2311
+ * Strongly type-aware conditional statement which checks whether a value is
2312
+ * a _true_ and returns one of two values (strongly typed) based on the evaluation
2313
+ * of this criteria.
2314
+ *
2315
+ * @param val the value being tested
2316
+ * @param ifVal the value (strongly typed) returned if val is _true_ value
2317
+ * @param elseVal the value (strongly typed) returned if val is NOT a _true_ value
2318
+ */
2319
+ declare function ifTrue<T extends Narrowable, IF, ELSE>(val: T, ifVal: IF, elseVal: ELSE): IsTrue<T> extends true ? IF : ELSE;
2320
+
2321
+ declare function isUndefined<T extends Narrowable>(i: T): undefined extends T ? true : false;
2322
+ /**
2323
+ * **ifUndefined**
2324
+ *
2325
+ * Strongly type-aware conditional statement which checks whether a value is
2326
+ * _undefined_ and returns one of two values (strongly typed) based on the evaluation
2327
+ * of this criteria.
2328
+ *
2329
+ * @param val the value being tested
2330
+ * @param ifVal the value (strongly typed) returned if val is `undefined`
2331
+ * @param elseVal the value (strongly typed) returned if val is NOT `undefined`
2332
+ */
2333
+ declare function ifUndefined<T extends Narrowable, IF extends Narrowable, ELSE extends Narrowable>(val: T, ifVal: IF, elseVal: ELSE): IsUndefined<T> extends true ? IF : ELSE;
2334
+
2335
+ type Type<T extends any, V extends Function> = {
2336
+ name: string;
2337
+ type: T;
2338
+ typeGuard: TypeGuard<T>;
2339
+ is: V;
2340
+ };
2341
+ declare const typeApi: () => {
2342
+ readonly string: Type<string, typeof isString>;
2343
+ readonly boolean: Type<boolean, typeof isBoolean>;
2344
+ readonly number: Type<number, typeof isNumber>;
2345
+ readonly function: Type<Function | (Function & {
2346
+ [key: string]: any;
2347
+ }), typeof isFunction>;
2348
+ readonly null: Type<null, typeof isNull>;
2349
+ readonly symbol: Type<symbol, typeof isSymbol>;
2350
+ readonly undefined: Type<undefined, typeof isUndefined>;
2351
+ readonly true: Type<true, typeof isTrue>;
2352
+ readonly false: Type<false, typeof isFalse>;
2353
+ readonly object: Type<Record<string, Narrowable>, typeof isObject>;
2354
+ readonly array: Type<any[], typeof isArray>;
2320
2355
  };
2356
+ type TypeApi = ReturnType<typeof typeApi>;
2357
+ declare function isType<T extends any, V extends Function>(t: unknown): t is Type<T, V>;
2358
+ type TypeDefinition<T extends any, V extends Function> = (defn: TypeApi) => Type<T, V>;
2359
+ declare function type<T extends any, V extends Function>(fn: TypeDefinition<T, V>): Type<T, V>;
2360
+
2361
+ /**
2362
+ * **withValue**
2363
+ *
2364
+ * Reduces a dictionary object -- in both _type_ and _run-time_ structure -- to only those
2365
+ * key/value pairs which have a specified value. For instance:
2366
+ *
2367
+ * ```ts
2368
+ * const obj = { foo: 1, bar: 2, message: "hi there" };
2369
+ * // { message: "hi there" }
2370
+ * const onlyStrings = withValue(t => t.string)(obj);
2371
+ * // { foo: 1 }
2372
+ * const justOne = withValue(t => t.literal(1))(obj);
2373
+ * ```
2374
+ *
2375
+ * Note: _often useful to provide run-time type profiles with the_ `inferredType` _utility_
2376
+ */
2377
+ declare function withValue<T extends any, V extends Function>(td: TypeDefinition<T, V>): <N extends Narrowable, R extends Record<string, N>>(obj: R) => ExpandRecursively<Pick<R, KeysWithValue<T, R>>>;
2321
2378
 
2322
- declare type Omit$1<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
2379
+ type Omit$1<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
2323
2380
  interface IConfigurator<C = {}> {
2324
2381
  set<V, K extends string, KV = {
2325
2382
  [U in K]: V;
@@ -2383,4 +2440,4 @@ interface IFluentConfigurator<C> {
2383
2440
  */
2384
2441
  declare function FluentConfigurator<I>(initial?: I): IFluentConfigurator<{}>;
2385
2442
 
2386
- export { AllCaps, Alpha, AlphaNumeric, Api, ApiFunction, ApiValue, AppendToDictionary, AppendToObject, ArrConcat, Array$1 as Array, ArrayConverter, AsArray, AsFinalizedConfig, AssertExtends, Bracket, Break, CamelCase, CapitalizeWords, Cardinality, Cardinality0, Cardinality1, CardinalityExplicit, CardinalityFilter0, CardinalityFilter1, CardinalityIn, CardinalityInput, CardinalityNode, CardinalityOut, CardinalityTuple, ClosingBracket, Condition, ConditionFilter, Configurator, ConfiguredMap, Constructor, DEFAULT_MANY_TO_ONE_MAPPING, DEFAULT_ONE_TO_MANY_MAPPING, DEFAULT_ONE_TO_ONE_MAPPING, DashToSnake, DashUppercase, Dasherize, DecomposeMapConfig, DefaultManyToOneMapping, DefaultOneToManyMapping, DefaultOneToOneMapping, DefinePropertiesApi, DictArrApi, DictArray, DictArrayFilterCallback, DictArrayKv, DictChangeValue, DictFromKv, DictKvTuple, DictPartialApplication, DictPrependWithFn, DictReturnValues, DynamicRule, DynamicRuleSet, Email, EnumValues, ExpandRecursively, ExpectExtends, ExplicitFunction, Extends, ExtendsClause, ExtendsNarrowlyClause, FilterContains, FilterDefn, FilterEnds, FilterEquals, FilterFn, FilterGreaterThan, FilterIs, FilterLessThan, FilterNotEqual, FilterStarts, FinalReturn, FinalizedMapConfig, First, FirstKey, FirstKeyValue, FirstOfEach, FluentConfigurator, FluentFunction, FromDictArray, FunctionType, GeneralDictionary, Get, HasUppercase, IConfigurator, IFluentConfigurator, If, IfBooleanLiteral, IfExtends, IfExtendsThen, IfLiteral, IfNumericLiteral, IfObject, IfOptionalLiteral, IfScalar, IfStringLiteral, Include, Includes, IntersectingKeys, IsArray, IsBoolean, IsBooleanLiteral, IsCapitalized, IsFalse, IsFunction, IsLiteral, IsNull, IsNumber, IsNumericLiteral, IsObject, IsOptionalLiteral, IsScalar, IsString, IsStringLiteral, IsTrue, KebabCase, KeyValue, KeyedRecord, Keys, KeysWithValue, KvFrom, KvTuple, LastInUnion, LeftWhitespace, Length, LogicFunction, LogicalCombinator, LowerAllCaps, LowerAlpha, ManyToMany, ManyToOne, ManyToZero, MapCard, MapCardinality, MapCardinalityFrom, MapCardinalityIllustrated, MapConfig, MapFn, MapFnInput, MapFnOutput, MapIR, MapInput, MapInputFrom, MapOR, MapOutput, MapOutputFrom, MapTo, Mapper, MapperApi, MaybeFalse, MaybeTrue, Model, Mutable, MutableProps, MutationFunction, MutationIdentity, Narrowable, NonAlpha, NonNumericKeys, NonStringKeys, Not, NotFilter, Numeric, NumericFilter, NumericKeys, NumericString, ObjectType, OneToMany, OneToOne, OneToZero, Opaque, OpeningBracket, OptRequired, OptionalKeys, OptionalProps, Parenthesis, PascalCase, Pluralize, PrivateKey, PrivateKeys, PublicKeys, Punctuation, PureFluentApi, Replace, RequireProps, RequiredKeys, RequiredProps, Retain, RightWhitespace, RuleDefinition, RuntimeProp, RuntimeType, SameKeys, SecondOfEach, SimplifyObject, SnakeCase, SpecialCharacters, StringDelimiter, StringFilter, StringKeys, StringLength, ToFluent, Transformer, Trim, TrimLeft, TrimRight, TupleToUnion, Type, TypeApi, TypeCondition, TypeDefault, TypeDefinition, TypeGuard, TypeOptions, UndefinedArrayIsUnknown, UndefinedTreatment, UndefinedValue, UnionToIntersection, UnionToTuple, UniqueDictionary, UniqueForProp, Uniqueness, UnwrapNot, UpperAlpha, ValueTuple, ValueTypeFunc, ValueTypes, Where, WhereNot, Whitespace, Widen, WithNumericKeys, WithStringKeys, WithValue, ZeroToMany, ZeroToOne, ZeroToZero, ZipCode, and, api, arrayToKeyLookup, arrayToObject, asArray, condition, createFnWithProps, createMutationFunction, defineProperties, defineType, dictArr, dictToKv, dictionaryTransform, entries, filter, filterDictArray, fnWithProps, groupBy, idLiteral, idTypeGuard, identity, ifBoolean, ifNull, ifNumber, ifString, ifTrue, ifTypeOf, ifUndefined, isArray, isBoolean, isFalse, isFunction, isNotFilter, isNull, isNumber, isNumericFilter, isObject, isString, isSymbol, isTrue, isType, isUndefined, keys, kindLiteral, kv, kvToDict, literal, mapTo, mapToDict, mapToFn, mapValues, nameLiteral, not, or, randomString, readonlyFnWithProps, ruleSet, strArrayToDict, type, typeApi, uuid, valueTypes, withValue };
2443
+ export { AfterFirst, AllCaps, Alpha, AlphaNumeric, AnyFunction, Api, ApiFunction, ApiValue, AppendToDictionary, AppendToObject, ArrConcat, Array$1 as Array, ArrayConverter, AsArray, AsFinalizedConfig, AssertExtends, Box, BoxValue, BoxedFnParams, BoxedReturn, Bracket, Break, CamelCase, CapitalizeWords, Cardinality, Cardinality0, Cardinality1, CardinalityExplicit, CardinalityFilter0, CardinalityFilter1, CardinalityIn, CardinalityInput, CardinalityNode, CardinalityOut, CardinalityTuple, ClosingBracket, Condition, ConditionFilter, Configurator, ConfiguredMap, Constructor, DEFAULT_MANY_TO_ONE_MAPPING, DEFAULT_ONE_TO_MANY_MAPPING, DEFAULT_ONE_TO_ONE_MAPPING, DashToSnake, DashUppercase, Dasherize, DecomposeMapConfig, DefaultManyToOneMapping, DefaultOneToManyMapping, DefaultOneToOneMapping, DefinePropertiesApi, DictArrApi, DictArray, DictArrayFilterCallback, DictArrayKv, DictChangeValue, DictFromKv, DictKvTuple, DictPartialApplication, DictPrependWithFn, DictReturnValues, DomainName, DynamicRule, DynamicRuleSet, Email, EndsWith, EnumValues, ExpandRecursively, ExpectExtends, ExplicitFunction, Extends, FilterContains, FilterDefn, FilterEnds, FilterEquals, FilterFn, FilterGreaterThan, FilterIs, FilterLessThan, FilterNotEqual, FilterStarts, FinalReturn, FinalizedMapConfig, First, FirstKey, FirstKeyValue, FirstOfEach, FirstOrUndefined, FirstString, FluentConfigurator, FluentFunction, FnShape, FromDictArray, FullyQualifiedUrl, FunctionType, GeneralDictionary, Get, HasUppercase, HybridFunction, IConfigurator, IFluentConfigurator, If, IfBooleanLiteral, IfExtends, IfExtendsThen, IfLiteral, IfNumericLiteral, IfObject, IfOptionalLiteral, IfScalar, IfStartsWith, IfStringLiteral, Include, Includes, IntersectingKeys, Ipv4, IsArray, IsBoolean, IsBooleanLiteral, IsCapitalized, IsFalse, IsFunction, IsLiteral, IsNull, IsNumber, IsNumericLiteral, IsObject, IsOptionalLiteral, IsScalar, IsStringLiteral, IsTrue, KebabCase, KeyValue, KeyedRecord, Keys, KeysWithValue, KvFrom, KvTuple, LastInUnion, LeftWhitespace, Length, LogicFunction, LogicalCombinator, LowerAllCaps, LowerAlpha, ManyToMany, ManyToOne, ManyToZero, MapCard, MapCardinality, MapCardinalityFrom, MapCardinalityIllustrated, MapConfig, MapFn, MapFnInput, MapFnOutput, MapIR, MapInput, MapInputFrom, MapOR, MapOutput, MapOutputFrom, MapTo, Mapper, MapperApi, MaybeFalse, MaybeTrue, Mutable, MutableProps, NarrowBox, Narrowable, NetworkProtocol, NonAlpha, NonNumericKeys, NonStringKeys, Not, NotFilter, Numeric, NumericFilter, NumericKeys, NumericString, ObjectType, OneToMany, OneToOne, OneToZero, Opaque, OpeningBracket, OptRequired, OptionalKeys, OptionalProps, Parenthesis, PascalCase, Pluralize, PrivateKey, PrivateKeys, PublicKeys, Punctuation, PureFluentApi, RelativeUrl, Replace, RequireProps, RequiredKeys, RequiredProps, Retain, RightWhitespace, RuleDefinition, RuntimeProp, RuntimeType, SameKeys, SecondOfEach, SimpleFunction, SimplifyObject, SnakeCase, SpecialCharacters, Split, StartsWith, StringDelimiter, StringFilter, StringKeys, StringLength, Suggest, SuggestNumeric, ToFluent, Transformer, Trim, TrimLeft, TrimRight, TupleToUnion, Type, TypeApi, TypeDefault, TypeDefinition, TypeGuard, TypeOptions, Unbox, UndefinedArrayIsUnknown, UndefinedTreatment, UndefinedValue, UnionToIntersection, UnionToTuple, UniqueDictionary, UniqueForProp, Uniqueness, UnwrapNot, UpperAlpha, UrlBuilder, VariableName, Where, WhereNot, Whitespace, Widen, WithNumericKeys, WithStringKeys, WithValue, ZeroToMany, ZeroToOne, ZeroToZero, ZipCode, and, api, arrayToKeyLookup, arrayToObject, asArray, box, condition, createFnWithProps, defineProperties, defineType, dictArr, dictToKv, dictionaryTransform, entries, filter, filterDictArray, fnWithProps, groupBy, idLiteral, idTypeGuard, identity, ifBoolean, ifNull, ifNumber, ifString, ifTrue, ifUndefined, isArray, isBoolean, isBox, isFalse, isFunction, isNotFilter, isNull, isNumber, isNumericFilter, isObject, isString, isSymbol, isTrue, isType, isUndefined, keys, kindLiteral, kv, kvToDict, literal, mapTo, mapToDict, mapToFn, mapValues, nameLiteral, not, or, readonlyFnWithProps, ruleSet, strArrayToDict, type, typeApi, unbox, withValue };