inferred-types 0.28.4 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -807,7 +807,7 @@ declare const mapToDict: MapperApi;
807
807
  * const many2one = mapTo.manyToOne().map<I,O>( ... );
808
808
  * ```
809
809
  */
810
- declare const mapTo: (<I, O>(map: (source: I) => O[]) => <S extends I | I[]>(source: S) => S extends I[] ? O[] : O[] | null) & MapperApi;
810
+ declare const mapTo: (<I, O>(map: (source: I) => O[]) => Mapper<I, O, FinalizedMapConfig<"req", "I -> O[]", "opt">>) & MapperApi;
811
811
 
812
812
  /**
813
813
  * Expresses relationship between inputs/outputs:
@@ -832,9 +832,11 @@ interface MapConfig<IR extends OptRequired | undefined = undefined, D extends Ma
832
832
  cardinality?: D;
833
833
  /**
834
834
  * Whether calls to the final `MapFn` will be logged to stderr
835
- * for debugging purposes. Defaults to false.
835
+ * for debugging purposes. Defaults to false; if you specify
836
+ * a _string_ for a value that will be sent to stderr along
837
+ * with other debugging info.
836
838
  */
837
- debug?: boolean;
839
+ debug?: boolean | string;
838
840
  }
839
841
  /**
840
842
  * A finalized configuration of a **mapTo** mapper functions cardinality
@@ -843,8 +845,9 @@ interface MapConfig<IR extends OptRequired | undefined = undefined, D extends Ma
843
845
  * Note: _this configuration does _not_ yet include the actual mapping
844
846
  * configuration between the input and output._
845
847
  */
846
- declare type FinalizedMapConfig<IR extends OptRequired = MapIR<DefaultOneToManyMapping>, D extends MapCardinalityIllustrated = MapCard<DefaultOneToManyMapping>, OR extends OptRequired = MapOR<DefaultOneToManyMapping>> = Required<MapConfig<IR, D, OR>> & {
848
+ 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">> & {
847
849
  finalized: true;
850
+ debug: boolean | string;
848
851
  };
849
852
  /**
850
853
  * User configuration exposed by a config function which specifies the
@@ -857,9 +860,10 @@ declare type MapCardinalityConfig<IR extends OptRequired | undefined, OR extends
857
860
  output?: OR;
858
861
  /**
859
862
  * Whether calls to the final `MapFn` will be logged to stderr
860
- * for debugging purposes. Defaults to false.
863
+ * for debugging purposes. Defaults to false; if you set to a string
864
+ * value than this will be echoed out with stderr.
861
865
  */
862
- debug?: boolean;
866
+ debug?: boolean | string;
863
867
  };
864
868
  /**
865
869
  * **ConfiguredMap**
@@ -869,10 +873,11 @@ declare type MapCardinalityConfig<IR extends OptRequired | undefined, OR extends
869
873
  * method which allows the user configure the specifics of the mapping.
870
874
  */
871
875
  declare type ConfiguredMap<C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = {
872
- map: <I, O>(map: MapTo<I, O, C>) => MapFn<I, O, C>;
876
+ map: <I, O>(map: MapTo<I, O, C>) => Mapper<I, O, C>;
873
877
  input: MapIR<C>;
874
878
  cardinality: MapCard<C>;
875
879
  output: MapOR<C>;
880
+ debug: boolean | string;
876
881
  };
877
882
  /**
878
883
  * Extracts the IR, Cardinality, and OR generics from a FinalizedMapConfig
@@ -965,6 +970,23 @@ declare type MapFnInput<I, IR extends OptRequired, D extends MapCardinalityIllus
965
970
  * ```
966
971
  */
967
972
  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>>;
973
+ /**
974
+ * **Mapper**
975
+ *
976
+ * A fully configured _mapper_ stemming from the **mapTo()** utility. It is both a mapping
977
+ * function and a dictionary which describes the mapper's properties.
978
+ * ```ts
979
+ * const m = mapTo.oneToOne().map( ... );
980
+ * const mapped = m(inputs);
981
+ * const mappedOver = inputs.map(m);
982
+ * ```
983
+ */
984
+ declare type Mapper<I, O, C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>> = {
985
+ input: MapIR<C>;
986
+ output: MapOR<C>;
987
+ cardinality: MapCard<C>;
988
+ debug: boolean | string;
989
+ } & MapFn<I, O, C>;
968
990
 
969
991
  /**
970
992
  * Given a dictionary of type `<T>`, this utility function will
@@ -2255,4 +2277,4 @@ interface IFluentConfigurator<C> {
2255
2277
  */
2256
2278
  declare function FluentConfigurator<I>(initial?: I): IFluentConfigurator<{}>;
2257
2279
 
2258
- 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, 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, MapCardinalityIllustrated, MapConfig, MapFn, MapFnInput, MapFnOutput, MapIR, MapInput, MapOR, MapOutput, MapTo, 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, ifTypeOf, 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 };
2280
+ 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, 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, MapCardinalityIllustrated, MapConfig, MapFn, MapFnInput, MapFnOutput, MapIR, MapInput, MapOR, MapOutput, 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, ifTypeOf, 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 };
package/dist/index.js CHANGED
@@ -611,39 +611,40 @@ var DEFAULT_MANY_TO_ONE_MAPPING = toFinalizedConfig({
611
611
  output: "req",
612
612
  cardinality: "I[] -> O"
613
613
  });
614
- var mapper = (config) => (map) => {
615
- return (source) => {
616
- const isArray2 = config.cardinality === "I -> O[]" && Array.isArray(source) ? true : config.cardinality === "I[] -> O" && Array.isArray(source) && Array.isArray(source[0]) ? true : false;
617
- if (isArray2) {
618
- const output = source.flatMap(map);
619
- if (config.debug) {
620
- console.error(
621
- `MapFn[${config.input}, ${config.cardinality}, ${config.output}] received:
614
+ var debugMsg = (config, source, output) => {
615
+ if (config.debug) {
616
+ console.error(
617
+ `MapFn[${typeof config.output === "string" ? `${config.output}, ` : ""}${config.input}, ${config.cardinality}, ${config.output}] received:
622
618
 
623
619
  ${JSON.stringify(source)}
624
620
 
625
621
  And produced: ${JSON.stringify(
626
- output
627
- )}
622
+ output
623
+ )}
628
624
 
629
625
  `
630
- );
631
- }
626
+ );
627
+ }
628
+ };
629
+ var mapper = (config) => (map) => {
630
+ const fn = (source) => {
631
+ const isArray2 = config.cardinality === "I -> O[]" && Array.isArray(source) ? true : config.cardinality === "I[] -> O" && Array.isArray(source) && Array.isArray(source[0]) ? true : false;
632
+ if (isArray2) {
633
+ const output = source.flatMap(map);
634
+ debugMsg(config, source, output);
632
635
  return output;
633
636
  } else {
634
637
  const output = map(source);
635
- if (config.debug) {
636
- console.error(
637
- `MapFn[${config.input}, ${config.cardinality}, ${config.output}] received:
638
-
639
- ${JSON.stringify(source)}
640
- And produced: ${JSON.stringify(output)}
641
- `
642
- );
643
- }
638
+ debugMsg(config, source, output);
644
639
  return output;
645
640
  }
646
641
  };
642
+ return createFnWithProps(fn, {
643
+ input: config.input,
644
+ output: config.output,
645
+ cardinality: config.cardinality,
646
+ debug: config.debug
647
+ });
647
648
  };
648
649
  var setMapper = (config = { input: void 0, output: void 0, cardinality: void 0 }, defaultValue) => ({
649
650
  map: (source) => {
@@ -655,7 +656,8 @@ var setMapper = (config = { input: void 0, output: void 0, cardinality: void 0 }
655
656
  },
656
657
  input: (config == null ? void 0 : config.input) || defaultValue.input,
657
658
  output: (config == null ? void 0 : config.output) || defaultValue.output,
658
- cardinality: (config == null ? void 0 : config.cardinality) || defaultValue.cardinality
659
+ cardinality: (config == null ? void 0 : config.cardinality) || defaultValue.cardinality,
660
+ debug: (config == null ? void 0 : config.debug) || false
659
661
  });
660
662
  var mapToFn = (map) => {
661
663
  return mapper(DEFAULT_ONE_TO_MANY_MAPPING)(map);
package/dist/index.mjs CHANGED
@@ -520,39 +520,40 @@ var DEFAULT_MANY_TO_ONE_MAPPING = toFinalizedConfig({
520
520
  output: "req",
521
521
  cardinality: "I[] -> O"
522
522
  });
523
- var mapper = (config) => (map) => {
524
- return (source) => {
525
- const isArray2 = config.cardinality === "I -> O[]" && Array.isArray(source) ? true : config.cardinality === "I[] -> O" && Array.isArray(source) && Array.isArray(source[0]) ? true : false;
526
- if (isArray2) {
527
- const output = source.flatMap(map);
528
- if (config.debug) {
529
- console.error(
530
- `MapFn[${config.input}, ${config.cardinality}, ${config.output}] received:
523
+ var debugMsg = (config, source, output) => {
524
+ if (config.debug) {
525
+ console.error(
526
+ `MapFn[${typeof config.output === "string" ? `${config.output}, ` : ""}${config.input}, ${config.cardinality}, ${config.output}] received:
531
527
 
532
528
  ${JSON.stringify(source)}
533
529
 
534
530
  And produced: ${JSON.stringify(
535
- output
536
- )}
531
+ output
532
+ )}
537
533
 
538
534
  `
539
- );
540
- }
535
+ );
536
+ }
537
+ };
538
+ var mapper = (config) => (map) => {
539
+ const fn = (source) => {
540
+ const isArray2 = config.cardinality === "I -> O[]" && Array.isArray(source) ? true : config.cardinality === "I[] -> O" && Array.isArray(source) && Array.isArray(source[0]) ? true : false;
541
+ if (isArray2) {
542
+ const output = source.flatMap(map);
543
+ debugMsg(config, source, output);
541
544
  return output;
542
545
  } else {
543
546
  const output = map(source);
544
- if (config.debug) {
545
- console.error(
546
- `MapFn[${config.input}, ${config.cardinality}, ${config.output}] received:
547
-
548
- ${JSON.stringify(source)}
549
- And produced: ${JSON.stringify(output)}
550
- `
551
- );
552
- }
547
+ debugMsg(config, source, output);
553
548
  return output;
554
549
  }
555
550
  };
551
+ return createFnWithProps(fn, {
552
+ input: config.input,
553
+ output: config.output,
554
+ cardinality: config.cardinality,
555
+ debug: config.debug
556
+ });
556
557
  };
557
558
  var setMapper = (config = { input: void 0, output: void 0, cardinality: void 0 }, defaultValue) => ({
558
559
  map: (source) => {
@@ -564,7 +565,8 @@ var setMapper = (config = { input: void 0, output: void 0, cardinality: void 0 }
564
565
  },
565
566
  input: (config == null ? void 0 : config.input) || defaultValue.input,
566
567
  output: (config == null ? void 0 : config.output) || defaultValue.output,
567
- cardinality: (config == null ? void 0 : config.cardinality) || defaultValue.cardinality
568
+ cardinality: (config == null ? void 0 : config.cardinality) || defaultValue.cardinality,
569
+ debug: (config == null ? void 0 : config.debug) || false
568
570
  });
569
571
  var mapToFn = (map) => {
570
572
  return mapper(DEFAULT_ONE_TO_MANY_MAPPING)(map);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inferred-types",
3
- "version": "0.28.4",
3
+ "version": "0.29.0",
4
4
  "description": "Functions which provide useful type inference on TS projects",
5
5
  "license": "MIT",
6
6
  "author": "Ken Snyder<ken@ken.net>",
@@ -37,9 +37,11 @@ export interface MapConfig<
37
37
  cardinality?: D;
38
38
  /**
39
39
  * Whether calls to the final `MapFn` will be logged to stderr
40
- * for debugging purposes. Defaults to false.
40
+ * for debugging purposes. Defaults to false; if you specify
41
+ * a _string_ for a value that will be sent to stderr along
42
+ * with other debugging info.
41
43
  */
42
- debug?: boolean;
44
+ debug?: boolean | string;
43
45
  }
44
46
 
45
47
  /**
@@ -53,7 +55,7 @@ export type FinalizedMapConfig<
53
55
  IR extends OptRequired = MapIR<DefaultOneToManyMapping>,
54
56
  D extends MapCardinalityIllustrated = MapCard<DefaultOneToManyMapping>,
55
57
  OR extends OptRequired = MapOR<DefaultOneToManyMapping>
56
- > = Required<MapConfig<IR, D, OR>> & { finalized: true };
58
+ > = Required<Omit<MapConfig<IR, D, OR>, "debug">> & { finalized: true; debug: boolean | string };
57
59
 
58
60
  /**
59
61
  * User configuration exposed by a config function which specifies the
@@ -69,9 +71,10 @@ type MapCardinalityConfig<
69
71
  output?: OR;
70
72
  /**
71
73
  * Whether calls to the final `MapFn` will be logged to stderr
72
- * for debugging purposes. Defaults to false.
74
+ * for debugging purposes. Defaults to false; if you set to a string
75
+ * value than this will be echoed out with stderr.
73
76
  */
74
- debug?: boolean;
77
+ debug?: boolean | string;
75
78
  };
76
79
 
77
80
  /**
@@ -84,10 +87,11 @@ type MapCardinalityConfig<
84
87
  export type ConfiguredMap<
85
88
  C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>
86
89
  > = {
87
- map: <I, O>(map: MapTo<I, O, C>) => MapFn<I, O, C>;
90
+ map: <I, O>(map: MapTo<I, O, C>) => Mapper<I, O, C>;
88
91
  input: MapIR<C>;
89
92
  cardinality: MapCard<C>;
90
93
  output: MapOR<C>;
94
+ debug: boolean | string;
91
95
  };
92
96
 
93
97
  /**
@@ -357,3 +361,25 @@ export type MapFn<
357
361
  : <S extends MapFnInput<I, MapIR<C>, MapCard<C>>>(
358
362
  source: S
359
363
  ) => MapFnOutput<I, O, S, MapOR<C>, MapCard<C>>;
364
+
365
+ /**
366
+ * **Mapper**
367
+ *
368
+ * A fully configured _mapper_ stemming from the **mapTo()** utility. It is both a mapping
369
+ * function and a dictionary which describes the mapper's properties.
370
+ * ```ts
371
+ * const m = mapTo.oneToOne().map( ... );
372
+ * const mapped = m(inputs);
373
+ * const mappedOver = inputs.map(m);
374
+ * ```
375
+ */
376
+ export type Mapper<
377
+ I,
378
+ O,
379
+ C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>
380
+ > = {
381
+ input: MapIR<C>;
382
+ output: MapOR<C>;
383
+ cardinality: MapCard<C>;
384
+ debug: boolean | string;
385
+ } & MapFn<I, O, C>;
@@ -1,16 +1,13 @@
1
1
  import {
2
2
  FinalizedMapConfig,
3
3
  MapCardinalityIllustrated,
4
- MapFnInput,
5
4
  MapperApi,
6
5
  MapTo,
7
6
  AsFinalizedConfig,
8
7
  MapConfig,
9
8
  ConfiguredMap,
10
- MapFnOutput,
11
- MapIR,
12
- MapCard,
13
- MapOR,
9
+ Mapper,
10
+ MapFn,
14
11
  } from "src/types/dictionary";
15
12
  import { OptRequired } from "src/types/literal-unions";
16
13
  import { createFnWithProps } from "../createFnWithProps";
@@ -49,15 +46,38 @@ export type DefaultOneToManyMapping = typeof DEFAULT_ONE_TO_MANY_MAPPING;
49
46
  export type DefaultOneToOneMapping = typeof DEFAULT_ONE_TO_ONE_MAPPING;
50
47
  export type DefaultManyToOneMapping = typeof DEFAULT_MANY_TO_ONE_MAPPING;
51
48
 
49
+ const debugMsg = <C extends FinalizedMapConfig<any, any, any>>(
50
+ config: C,
51
+ source: any,
52
+ output: any
53
+ ) => {
54
+ if (config.debug) {
55
+ console.error(
56
+ `MapFn[${typeof config.output === "string" ? `${config.output}, ` : ""}${config.input}, ${
57
+ config.cardinality
58
+ }, ${config.output}] received:\n\n${JSON.stringify(source)}\n\nAnd produced: ${JSON.stringify(
59
+ output
60
+ )}\n\n`
61
+ );
62
+ }
63
+ };
64
+
52
65
  /**
53
66
  * The single implementation for all mapping
54
67
  */
55
68
  const mapper =
56
- <C extends FinalizedMapConfig<OptRequired, MapCardinalityIllustrated, OptRequired>>(config: C) =>
57
- <I, O>(map: MapTo<I, O, C>) => {
58
- return <S extends MapFnInput<I, MapIR<C>, MapCard<C>>>(
59
- source?: S
60
- ): MapFnOutput<I, O, S, MapOR<C>, MapCard<C>> => {
69
+ <
70
+ //
71
+ C extends FinalizedMapConfig<
72
+ OptRequired, //
73
+ MapCardinalityIllustrated,
74
+ OptRequired
75
+ >
76
+ >(
77
+ config: C
78
+ ) =>
79
+ <I, O>(map: MapTo<I, O, C>): Mapper<I, O, C> => {
80
+ const fn: MapFn<I, O, C> = <S>(source: S) => {
61
81
  /**
62
82
  * Determine whether input is an array; this will be true
63
83
  */
@@ -77,32 +97,26 @@ const mapper =
77
97
  // item and this approach achieves this.
78
98
  // TODO: we should check that the approach below doesn't work for M:1 here
79
99
  // as well
80
- const output = (source as any).flatMap(map) as MapFnOutput<I, O, S, MapOR<C>, MapCard<C>>;
81
- if (config.debug) {
82
- console.error(
83
- `MapFn[${config.input}, ${config.cardinality}, ${
84
- config.output
85
- }] received:\n\n${JSON.stringify(source)}\n\nAnd produced: ${JSON.stringify(
86
- output
87
- )}\n\n`
88
- );
89
- }
100
+ const output = (source as any).flatMap(map);
101
+ debugMsg(config, source, output);
90
102
 
91
103
  return output;
92
104
  } else {
93
105
  // receive _all_ inputs provided as pass into ; this is just a single input unless the
94
106
  // cardinality is
95
- const output = map(source as any) as MapFnOutput<I, O, S, MapOR<C>, MapCard<C>>;
96
- if (config.debug) {
97
- console.error(
98
- `MapFn[${config.input}, ${config.cardinality}, ${
99
- config.output
100
- }] received:\n\n${JSON.stringify(source)}\nAnd produced: ${JSON.stringify(output)}\n`
101
- );
102
- }
107
+ const output = map(source as any);
108
+ debugMsg(config, source, output);
109
+
103
110
  return output;
104
111
  }
105
112
  };
113
+
114
+ return createFnWithProps(fn, {
115
+ input: config.input,
116
+ output: config.output,
117
+ cardinality: config.cardinality,
118
+ debug: config.debug,
119
+ });
106
120
  };
107
121
 
108
122
  /**
@@ -131,6 +145,7 @@ const setMapper = <
131
145
  input: config?.input || defaultValue.input,
132
146
  output: config?.output || defaultValue.output,
133
147
  cardinality: config?.cardinality || defaultValue.cardinality,
148
+ debug: config?.debug || false,
134
149
  });
135
150
 
136
151
  /**
@@ -6,6 +6,7 @@ import {
6
6
  AsFinalizedConfig,
7
7
  MapConfig,
8
8
  ConfiguredMap,
9
+ Mapper,
9
10
  } from "src/types/dictionary";
10
11
  import { describe, expect, it } from "vitest";
11
12
  import type { Expect, Equal } from "@type-challenges/utils";
@@ -169,37 +170,21 @@ describe("MapTo<I,O> and MapToFn<I,O>", () => {
169
170
  // map() function's parameters (unknown is I)
170
171
  Expect<Equal<[map: (source: unknown) => unknown], M1P>>,
171
172
  // map() function's return value
172
- Expect<
173
- Equal<<S extends unknown>(source: S) => S extends unknown[] ? unknown[] : unknown, M1R>
174
- >,
173
+ Expect<Equal<Mapper<unknown, unknown, FinalizedMapConfig<"req", "I -> O", "opt">>, M1R>>,
175
174
 
176
175
  // merged configuration is same as default for M:1
177
176
  Expect<Equal<C2, FinalizedMapConfig<"req", "I[] -> O", "req">>>,
178
177
  // map() function's parameters (unknown is I)
179
178
  Expect<Equal<[map: (source: unknown[]) => unknown], M2P>>,
180
179
  // map() function's return value
181
- Expect<
182
- Equal<
183
- <S extends unknown[] | unknown[][]>(
184
- source: S
185
- ) => S extends unknown[][] ? [unknown, ...unknown[]] : unknown,
186
- M2R
187
- >
188
- >,
180
+ Expect<Equal<Mapper<unknown, unknown, FinalizedMapConfig<"req", "I[] -> O", "req">>, M2R>>,
189
181
 
190
182
  // merged configuration should be M:1 default with an "opt" for output
191
183
  Expect<Equal<C3, FinalizedMapConfig<"req", "I[] -> O", "opt">>>,
192
184
  // map() function's parameters (unknown is I)
193
185
  Expect<Equal<[map: (source: unknown[]) => unknown | null], M3P>>,
194
186
  // map() function's return value
195
- Expect<
196
- Equal<
197
- <S extends unknown[] | unknown[][]>(
198
- source: S
199
- ) => S extends unknown[][] ? unknown[] : unknown,
200
- M3R
201
- >
202
- >
187
+ Expect<Equal<Mapper<unknown, unknown, FinalizedMapConfig<"req", "I[] -> O", "opt">>, M3R>>
203
188
  ];
204
189
 
205
190
  const cases: cases = [true, true, true, true, true, true, true, true, true];
@@ -269,6 +254,16 @@ describe("mapTo() utility function", () => {
269
254
  expect(c1.cardinality).toBe(MapCardinality.OneToMany);
270
255
  });
271
256
 
257
+ it("Mapper<I,O,C>", () => {
258
+ const m0 = mapTo.oneToOne();
259
+ const m1 = m0.map<I, I>((i) => i);
260
+
261
+ expect(m1.input).toBe("req");
262
+ expect(m1.output).toBe("req");
263
+ expect(m1.cardinality).toBe("I -> O");
264
+ expect(m1(i)).toEqual(i);
265
+ });
266
+
272
267
  it("M:1 conversion", () => {
273
268
  const m = mapTo
274
269
  .config({