@strictly/define 0.0.31 → 0.0.32

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.
@@ -1,3 +1,4 @@
1
+ import { map, UnreachableError, } from '@strictly/base';
1
2
  import { isAnnotatedValidator, mergeAnnotations, validate, } from 'validation/validator';
2
3
  import { TypeDefType, } from './Type';
3
4
  import { typeOfType, } from './typeOfType';
@@ -97,10 +98,31 @@ class ObjectTypeDefBuilder extends TypeDefBuilder {
97
98
  }
98
99
  class UnionTypeDefBuilder extends TypeDefBuilder {
99
100
  or(k, { definition: typeDef, }) {
100
- const { unions, } = this.definition;
101
+ const { unions, discriminator, } = this.definition;
102
+ // add the discriminator as a field to the underlying union type
103
+ const enhancedTypeDef = maybeAddDiscriminatorField(typeDef, discriminator, k);
101
104
  return new UnionTypeDefBuilder(Object.assign(Object.assign({}, this.definition), {
102
105
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
103
- unions: Object.assign(Object.assign({}, unions), { [k]: typeDef }) }));
106
+ unions: Object.assign(Object.assign({}, unions), { [k]: enhancedTypeDef }) }));
107
+ }
108
+ }
109
+ function maybeAddDiscriminatorField(t, discriminatorKey, discriminatorLiteral) {
110
+ if (discriminatorKey == null) {
111
+ return t;
112
+ }
113
+ switch (t.type) {
114
+ case TypeDefType.List:
115
+ case TypeDefType.Literal:
116
+ case TypeDefType.Record:
117
+ return t;
118
+ case TypeDefType.Object:
119
+ return Object.assign(Object.assign({}, t), { fields: Object.assign(Object.assign({}, t.fields), { [discriminatorKey]: literal([discriminatorLiteral]).readonly().required().narrow.definition }) });
120
+ case TypeDefType.Union:
121
+ return Object.assign(Object.assign({}, t), { unions: map(t.unions, (_k, v) => {
122
+ return maybeAddDiscriminatorField(v, discriminatorKey, discriminatorLiteral);
123
+ }) });
124
+ default:
125
+ throw new UnreachableError(t);
104
126
  }
105
127
  }
106
128
  export function literal(value) {
@@ -1,2 +1,2 @@
1
- export type StartingDepth = 7;
1
+ export type StartingDepth = 5;
2
2
  export type Depths = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
@@ -7,12 +7,12 @@ $ tsup
7
7
  CLI Target: es6
8
8
  CJS Build start
9
9
  ESM Build start
10
- CJS dist/index.cjs 35.88 KB
11
- CJS ⚡️ Build success in 88ms
12
- ESM dist/index.js 33.29 KB
13
- ESM ⚡️ Build success in 89ms
10
+ ESM dist/index.js 34.08 KB
11
+ ESM ⚡️ Build success in 119ms
12
+ CJS dist/index.cjs 36.67 KB
13
+ CJS ⚡️ Build success in 126ms
14
14
  DTS Build start
15
- DTS ⚡️ Build success in 7960ms
16
- DTS dist/index.d.cts 41.80 KB
17
- DTS dist/index.d.ts 41.80 KB
18
- Done in 9.24s.
15
+ DTS ⚡️ Build success in 5988ms
16
+ DTS dist/index.d.cts 41.82 KB
17
+ DTS dist/index.d.ts 41.82 KB
18
+ Done in 7.55s.
@@ -1,3 +1,3 @@
1
1
  yarn run v1.22.22
2
2
  $ tsc -b
3
- Done in 0.35s.
3
+ Done in 0.29s.
package/dist/index.cjs CHANGED
@@ -193,14 +193,7 @@ function copyUnion(typeDef, value, copier) {
193
193
  } = typeDef;
194
194
  if (discriminator != null) {
195
195
  const discriminatorValue = value[discriminator];
196
- const discriminatingUnion = __spreadProps(__spreadValues({}, internalCopyTo(
197
- unions[discriminatorValue],
198
- value,
199
- copier
200
- )), {
201
- [discriminator]: discriminatorValue
202
- });
203
- return copier(discriminatingUnion, typeDef);
196
+ return internalCopyTo(unions[discriminatorValue], value, copier);
204
197
  }
205
198
  const allTypeDefs = Object.values(unions);
206
199
  const variableTypeDefs = allTypeDefs.filter(function(typeDef2) {
@@ -417,7 +410,7 @@ function observeValue(v, def) {
417
410
  }
418
411
  );
419
412
  case 4 /* Object */:
420
- return (0, import_mobx.makeObservable)(
413
+ return (0, import_mobx.observable)(
421
414
  v,
422
415
  (0, import_base4.reduce)(
423
416
  def.fields,
@@ -800,6 +793,9 @@ function internalJsonValuePathToTypePath(typeDef, qualifiers, valueSteps, allowM
800
793
  }
801
794
  }
802
795
 
796
+ // types/builders.ts
797
+ var import_base9 = require("@strictly/base");
798
+
803
799
  // validation/validators/CompositeValidator.ts
804
800
  var CompositeValidator = class {
805
801
  constructor(...validators) {
@@ -1066,18 +1062,45 @@ var UnionTypeDefBuilder = class _UnionTypeDefBuilder extends TypeDefBuilder {
1066
1062
  definition: typeDef
1067
1063
  }) {
1068
1064
  const {
1069
- unions
1065
+ unions,
1066
+ discriminator
1070
1067
  } = this.definition;
1068
+ const enhancedTypeDef = maybeAddDiscriminatorField(typeDef, discriminator, k);
1071
1069
  return new _UnionTypeDefBuilder(
1072
1070
  __spreadProps(__spreadValues({}, this.definition), {
1073
1071
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1074
1072
  unions: __spreadProps(__spreadValues({}, unions), {
1075
- [k]: typeDef
1073
+ [k]: enhancedTypeDef
1076
1074
  })
1077
1075
  })
1078
1076
  );
1079
1077
  }
1080
1078
  };
1079
+ function maybeAddDiscriminatorField(t, discriminatorKey, discriminatorLiteral) {
1080
+ if (discriminatorKey == null) {
1081
+ return t;
1082
+ }
1083
+ switch (t.type) {
1084
+ case 2 /* List */:
1085
+ case 1 /* Literal */:
1086
+ case 3 /* Record */:
1087
+ return t;
1088
+ case 4 /* Object */:
1089
+ return __spreadProps(__spreadValues({}, t), {
1090
+ fields: __spreadProps(__spreadValues({}, t.fields), {
1091
+ [discriminatorKey]: literal([discriminatorLiteral]).readonly().required().narrow.definition
1092
+ })
1093
+ });
1094
+ case 5 /* Union */:
1095
+ return __spreadProps(__spreadValues({}, t), {
1096
+ unions: (0, import_base9.map)(t.unions, (_k, v) => {
1097
+ return maybeAddDiscriminatorField(v, discriminatorKey, discriminatorLiteral);
1098
+ })
1099
+ });
1100
+ default:
1101
+ throw new import_base9.UnreachableError(t);
1102
+ }
1103
+ }
1081
1104
  function literal(value) {
1082
1105
  return new TypeDefBuilder({
1083
1106
  type: 1 /* Literal */,
package/dist/index.d.cts CHANGED
@@ -149,7 +149,7 @@ declare function mobxCopy<T extends StrictType>(t: T, proto: ValueOfType<Readonl
149
149
 
150
150
  declare function equals<T extends Type>({ definition }: T, o1: ValueOfType<T>, o2: ValueOfType<T>): boolean;
151
151
 
152
- type StartingDepth = 7;
152
+ type StartingDepth = 5;
153
153
  type Depths = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
154
154
 
155
155
  type PathOf<Prefix extends string, Accessor extends string | number | symbol, SegmentOverride extends string | null = null> = SegmentOverride extends string ? `${Prefix}.${SegmentOverride}` : Accessor extends string | number ? `${Prefix}.${Accessor}` : never;
@@ -189,7 +189,7 @@ type FlattenedAccessorsOfType<T extends Type, Flattened extends Readonly<Record<
189
189
  type AnyValueType = any;
190
190
  type Setter<V> = (v: V) => void;
191
191
  type Mapper<R> = (t: StrictTypeDef, v: AnyValueType, setter: Setter<AnyValueType>, typePath: string, valuePath: string) => R;
192
- declare function flattenValueTo<T extends StrictType, M, R extends Readonly<Record<string, M>>>({ definition }: T, v: ValueOfType<T>, setter: Setter<ValueOfType<T>>, mapper: Mapper<M>, listIndicesToKeys?: Record<string, number[]>): R;
192
+ declare function flattenValueTo<T extends StrictType, M, R extends Readonly<Record<string, M>>>({ definition }: T, v: ValueOfType<ReadonlyTypeOfType<T>>, setter: Setter<ValueOfType<T>>, mapper: Mapper<M>, listIndicesToKeys?: Record<string, number[]>): R;
193
193
  declare function getUnionTypeDef<T extends UnionTypeDef>(typeDef: T, v: ValueOfType<ReadonlyTypeOfType<{
194
194
  definition: T;
195
195
  }>>): any;
package/dist/index.d.ts CHANGED
@@ -149,7 +149,7 @@ declare function mobxCopy<T extends StrictType>(t: T, proto: ValueOfType<Readonl
149
149
 
150
150
  declare function equals<T extends Type>({ definition }: T, o1: ValueOfType<T>, o2: ValueOfType<T>): boolean;
151
151
 
152
- type StartingDepth = 7;
152
+ type StartingDepth = 5;
153
153
  type Depths = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
154
154
 
155
155
  type PathOf<Prefix extends string, Accessor extends string | number | symbol, SegmentOverride extends string | null = null> = SegmentOverride extends string ? `${Prefix}.${SegmentOverride}` : Accessor extends string | number ? `${Prefix}.${Accessor}` : never;
@@ -189,7 +189,7 @@ type FlattenedAccessorsOfType<T extends Type, Flattened extends Readonly<Record<
189
189
  type AnyValueType = any;
190
190
  type Setter<V> = (v: V) => void;
191
191
  type Mapper<R> = (t: StrictTypeDef, v: AnyValueType, setter: Setter<AnyValueType>, typePath: string, valuePath: string) => R;
192
- declare function flattenValueTo<T extends StrictType, M, R extends Readonly<Record<string, M>>>({ definition }: T, v: ValueOfType<T>, setter: Setter<ValueOfType<T>>, mapper: Mapper<M>, listIndicesToKeys?: Record<string, number[]>): R;
192
+ declare function flattenValueTo<T extends StrictType, M, R extends Readonly<Record<string, M>>>({ definition }: T, v: ValueOfType<ReadonlyTypeOfType<T>>, setter: Setter<ValueOfType<T>>, mapper: Mapper<M>, listIndicesToKeys?: Record<string, number[]>): R;
193
193
  declare function getUnionTypeDef<T extends UnionTypeDef>(typeDef: T, v: ValueOfType<ReadonlyTypeOfType<{
194
194
  definition: T;
195
195
  }>>): any;
package/dist/index.js CHANGED
@@ -136,14 +136,7 @@ function copyUnion(typeDef, value, copier) {
136
136
  } = typeDef;
137
137
  if (discriminator != null) {
138
138
  const discriminatorValue = value[discriminator];
139
- const discriminatingUnion = __spreadProps(__spreadValues({}, internalCopyTo(
140
- unions[discriminatorValue],
141
- value,
142
- copier
143
- )), {
144
- [discriminator]: discriminatorValue
145
- });
146
- return copier(discriminatingUnion, typeDef);
139
+ return internalCopyTo(unions[discriminatorValue], value, copier);
147
140
  }
148
141
  const allTypeDefs = Object.values(unions);
149
142
  const variableTypeDefs = allTypeDefs.filter(function(typeDef2) {
@@ -174,7 +167,6 @@ import {
174
167
  UnreachableError as UnreachableError3
175
168
  } from "@strictly/base";
176
169
  import {
177
- makeObservable,
178
170
  observable
179
171
  } from "mobx";
180
172
 
@@ -372,7 +364,7 @@ function observeValue(v, def) {
372
364
  }
373
365
  );
374
366
  case 4 /* Object */:
375
- return makeObservable(
367
+ return observable(
376
368
  v,
377
369
  reduce3(
378
370
  def.fields,
@@ -767,6 +759,12 @@ function internalJsonValuePathToTypePath(typeDef, qualifiers, valueSteps, allowM
767
759
  }
768
760
  }
769
761
 
762
+ // types/builders.ts
763
+ import {
764
+ map as map3,
765
+ UnreachableError as UnreachableError8
766
+ } from "@strictly/base";
767
+
770
768
  // validation/validators/CompositeValidator.ts
771
769
  var CompositeValidator = class {
772
770
  constructor(...validators) {
@@ -1036,18 +1034,45 @@ var UnionTypeDefBuilder = class _UnionTypeDefBuilder extends TypeDefBuilder {
1036
1034
  definition: typeDef
1037
1035
  }) {
1038
1036
  const {
1039
- unions
1037
+ unions,
1038
+ discriminator
1040
1039
  } = this.definition;
1040
+ const enhancedTypeDef = maybeAddDiscriminatorField(typeDef, discriminator, k);
1041
1041
  return new _UnionTypeDefBuilder(
1042
1042
  __spreadProps(__spreadValues({}, this.definition), {
1043
1043
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1044
1044
  unions: __spreadProps(__spreadValues({}, unions), {
1045
- [k]: typeDef
1045
+ [k]: enhancedTypeDef
1046
1046
  })
1047
1047
  })
1048
1048
  );
1049
1049
  }
1050
1050
  };
1051
+ function maybeAddDiscriminatorField(t, discriminatorKey, discriminatorLiteral) {
1052
+ if (discriminatorKey == null) {
1053
+ return t;
1054
+ }
1055
+ switch (t.type) {
1056
+ case 2 /* List */:
1057
+ case 1 /* Literal */:
1058
+ case 3 /* Record */:
1059
+ return t;
1060
+ case 4 /* Object */:
1061
+ return __spreadProps(__spreadValues({}, t), {
1062
+ fields: __spreadProps(__spreadValues({}, t.fields), {
1063
+ [discriminatorKey]: literal([discriminatorLiteral]).readonly().required().narrow.definition
1064
+ })
1065
+ });
1066
+ case 5 /* Union */:
1067
+ return __spreadProps(__spreadValues({}, t), {
1068
+ unions: map3(t.unions, (_k, v) => {
1069
+ return maybeAddDiscriminatorField(v, discriminatorKey, discriminatorLiteral);
1070
+ })
1071
+ });
1072
+ default:
1073
+ throw new UnreachableError8(t);
1074
+ }
1075
+ }
1051
1076
  function literal(value) {
1052
1077
  return new TypeDefBuilder({
1053
1078
  type: 1 /* Literal */,
package/package.json CHANGED
@@ -38,7 +38,7 @@
38
38
  "test:watch": "vitest"
39
39
  },
40
40
  "type": "module",
41
- "version": "0.0.31",
41
+ "version": "0.0.32",
42
42
  "exports": {
43
43
  ".": {
44
44
  "import": {
@@ -195,15 +195,7 @@ function copyUnion<
195
195
  // is it a discriminated union with a struct?
196
196
  if (discriminator != null) {
197
197
  const discriminatorValue = value[discriminator]
198
- const discriminatingUnion = {
199
- ...internalCopyTo(
200
- unions[discriminatorValue],
201
- value,
202
- copier,
203
- ),
204
- [discriminator]: discriminatorValue,
205
- }
206
- return copier(discriminatingUnion, typeDef)
198
+ return internalCopyTo(unions[discriminatorValue], value, copier)
207
199
  }
208
200
 
209
201
  // is it a `<constant1> | <constant2> | X`? We can handle that
@@ -4,7 +4,6 @@ import {
4
4
  } from '@strictly/base'
5
5
  import {
6
6
  type IObservableFactory,
7
- makeObservable,
8
7
  observable,
9
8
  } from 'mobx'
10
9
  import { getUnionTypeDef } from 'transformers/flatteners/flattenValueTo'
@@ -49,7 +48,7 @@ function observeValue(
49
48
  )
50
49
  case TypeDefType.Object:
51
50
  // `makeObservable` only observes the specified props
52
- return makeObservable(
51
+ return observable(
53
52
  v,
54
53
  reduce(
55
54
  def.fields,
@@ -134,7 +134,7 @@ describe('copyTo', function () {
134
134
  )
135
135
 
136
136
  expect(c).toEqual({
137
- d: 'a',
137
+ d: '"a"',
138
138
  x: '1',
139
139
  })
140
140
  })
@@ -37,7 +37,7 @@ export function flattenValueTo<
37
37
  R extends Readonly<Record<string, M>>,
38
38
  >(
39
39
  { definition }: T,
40
- v: ValueOfType<T>,
40
+ v: ValueOfType<ReadonlyTypeOfType<T>>,
41
41
  setter: Setter<ValueOfType<T>>,
42
42
  mapper: Mapper<M>,
43
43
  // used to maintain keys when changing lists, note that the format for a list of three elements is
@@ -108,6 +108,7 @@ describe('flattenJsonValueToTypePathsOf', function () {
108
108
  $: '$',
109
109
  '$:x.a': '$:x.a',
110
110
  '$:x.b': '$:x.b',
111
+ '$:x.d': '$:x.d',
111
112
  })
112
113
  })
113
114
  })
@@ -136,12 +136,14 @@ describe('flattenTypeDefTo', function () {
136
136
  expect(flattened).toEqual({
137
137
  $: TypeDefType.Union,
138
138
  '$:a.a': TypeDefType.Literal,
139
+ '$:a.d': TypeDefType.Literal,
139
140
  '$:b.b': TypeDefType.Literal,
141
+ '$:b.d': TypeDefType.Literal,
140
142
  })
141
143
  })
142
144
 
143
145
  it('calls the mapper function', function () {
144
- expect(toTypeDefType).toHaveBeenCalledTimes(3)
146
+ expect(toTypeDefType).toHaveBeenCalledTimes(5)
145
147
  })
146
148
  })
147
149
  })
@@ -330,6 +330,7 @@ describe('flattenValueTo', function () {
330
330
  expect(flattened).toEqual({
331
331
  $: '{"d":"1","a":2}',
332
332
  ['$:1.a']: '2',
333
+ ['$:1.d']: '"1"',
333
334
  })
334
335
  })
335
336
  })
package/types/builders.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import {
2
2
  type IsFieldReadonly,
3
+ map,
4
+ UnreachableError,
3
5
  } from '@strictly/base'
4
6
  import {
5
7
  isAnnotatedValidator,
@@ -343,20 +345,56 @@ class UnionTypeDefBuilder<
343
345
  ): UnionTypeDefBuilder<E, C, D, Readonly<Record<K, T>> & U> {
344
346
  const {
345
347
  unions,
348
+ discriminator,
346
349
  } = this.definition
350
+ // add the discriminator as a field to the underlying union type
351
+ const enhancedTypeDef = maybeAddDiscriminatorField(typeDef, discriminator, k)
347
352
  return new UnionTypeDefBuilder<E, C, D, Readonly<Record<K, T>> & U>(
348
353
  {
349
354
  ...this.definition,
350
355
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
351
356
  unions: {
352
357
  ...unions,
353
- [k]: typeDef,
358
+ [k]: enhancedTypeDef,
354
359
  } as Readonly<Record<K, T>> & U,
355
360
  },
356
361
  )
357
362
  }
358
363
  }
359
364
 
365
+ function maybeAddDiscriminatorField<T extends TypeDef, K extends UnionKey>(
366
+ t: T,
367
+ discriminatorKey: string | null,
368
+ discriminatorLiteral: K,
369
+ ): T {
370
+ if (discriminatorKey == null) {
371
+ return t
372
+ }
373
+ switch (t.type) {
374
+ case TypeDefType.List:
375
+ case TypeDefType.Literal:
376
+ case TypeDefType.Record:
377
+ return t
378
+ case TypeDefType.Object:
379
+ return {
380
+ ...t,
381
+ fields: {
382
+ ...t.fields,
383
+ [discriminatorKey]: literal([discriminatorLiteral]).readonly().required().narrow.definition,
384
+ },
385
+ }
386
+ case TypeDefType.Union:
387
+ return {
388
+ ...t,
389
+ unions: map(t.unions, (_k, v) => {
390
+ return maybeAddDiscriminatorField(v, discriminatorKey, discriminatorLiteral)
391
+ }),
392
+ }
393
+ default:
394
+ throw new UnreachableError(t)
395
+ }
396
+ }
397
+
360
398
  export function literal<T>(value?: [T]): TypeDefBuilder<ValidatingLiteralTypeDef<never, {}, T>> {
361
399
  return new TypeDefBuilder({
362
400
  type: TypeDefType.Literal,
@@ -1,5 +1,5 @@
1
1
  // Unfortunately the TS compiler will infinitely loop if we don't give it a way of breaking out.
2
2
  // A starting depth of 10 (the maximum) will cause performance issues while developing
3
- export type StartingDepth = 7
3
+ export type StartingDepth = 5
4
4
  // Going much above a depth of 10 will also blow up
5
5
  export type Depths = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]