@strictly/define 0.0.1

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 (162) hide show
  1. package/.eslintrc.cjs +31 -0
  2. package/.out/index.d.ts +20 -0
  3. package/.out/index.js +20 -0
  4. package/.out/transformers/copies/copy.d.ts +4 -0
  5. package/.out/transformers/copies/copy.js +7 -0
  6. package/.out/transformers/copies/copy_to.d.ts +6 -0
  7. package/.out/transformers/copies/copy_to.js +91 -0
  8. package/.out/transformers/copies/mobx_copy.d.ts +5 -0
  9. package/.out/transformers/copies/mobx_copy.js +42 -0
  10. package/.out/transformers/copies/specs/copy_to.tests.d.ts +1 -0
  11. package/.out/transformers/copies/specs/copy_to.tests.js +97 -0
  12. package/.out/transformers/copies/specs/mobx_copy.tests.d.ts +1 -0
  13. package/.out/transformers/copies/specs/mobx_copy.tests.js +19 -0
  14. package/.out/transformers/flatteners/flatten_accessors_of.d.ts +5 -0
  15. package/.out/transformers/flatteners/flatten_accessors_of.js +11 -0
  16. package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.d.ts +3 -0
  17. package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.js +10 -0
  18. package/.out/transformers/flatteners/flatten_type_def_to.d.ts +4 -0
  19. package/.out/transformers/flatteners/flatten_type_def_to.js +49 -0
  20. package/.out/transformers/flatteners/flatten_type_defs_of.d.ts +3 -0
  21. package/.out/transformers/flatteners/flatten_type_defs_of.js +7 -0
  22. package/.out/transformers/flatteners/flatten_value_type_to.d.ts +11 -0
  23. package/.out/transformers/flatteners/flatten_value_type_to.js +79 -0
  24. package/.out/transformers/flatteners/flatten_value_types_of.d.ts +3 -0
  25. package/.out/transformers/flatteners/flatten_value_types_of.js +7 -0
  26. package/.out/transformers/flatteners/json_path.d.ts +2 -0
  27. package/.out/transformers/flatteners/json_path.js +14 -0
  28. package/.out/transformers/flatteners/specs/flatten_accessors_of.tests.d.ts +1 -0
  29. package/.out/transformers/flatteners/specs/flatten_accessors_of.tests.js +90 -0
  30. package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.d.ts +1 -0
  31. package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.js +94 -0
  32. package/.out/transformers/flatteners/specs/flatten_type_def_to.tests.d.ts +1 -0
  33. package/.out/transformers/flatteners/specs/flatten_type_def_to.tests.js +110 -0
  34. package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.d.ts +1 -0
  35. package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.js +17 -0
  36. package/.out/transformers/flatteners/specs/flatten_value_type_to.tests.d.ts +1 -0
  37. package/.out/transformers/flatteners/specs/flatten_value_type_to.tests.js +297 -0
  38. package/.out/transformers/flatteners/specs/flatten_value_types_of.tests.d.ts +1 -0
  39. package/.out/transformers/flatteners/specs/flatten_value_types_of.tests.js +37 -0
  40. package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.d.ts +1 -0
  41. package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.js +167 -0
  42. package/.out/transformers/flatteners/value_path_to_type_path.d.ts +2 -0
  43. package/.out/transformers/flatteners/value_path_to_type_path.js +96 -0
  44. package/.out/tsconfig.json +15 -0
  45. package/.out/tsconfig.tsbuildinfo +1 -0
  46. package/.out/tsup.config.d.ts +3 -0
  47. package/.out/tsup.config.js +12 -0
  48. package/.out/types/builders.d.ts +62 -0
  49. package/.out/types/builders.js +148 -0
  50. package/.out/types/definitions.d.ts +41 -0
  51. package/.out/types/definitions.js +26 -0
  52. package/.out/types/flattened.d.ts +2 -0
  53. package/.out/types/flattened.js +1 -0
  54. package/.out/types/flattened_accessors_of.d.ts +9 -0
  55. package/.out/types/flattened_accessors_of.js +1 -0
  56. package/.out/types/flattened_type_defs_of.d.ts +21 -0
  57. package/.out/types/flattened_type_defs_of.js +1 -0
  58. package/.out/types/flattened_value_types_of.d.ts +6 -0
  59. package/.out/types/flattened_value_types_of.js +1 -0
  60. package/.out/types/json_path_of.d.ts +1 -0
  61. package/.out/types/json_path_of.js +1 -0
  62. package/.out/types/json_paths_of.d.ts +16 -0
  63. package/.out/types/json_paths_of.js +1 -0
  64. package/.out/types/mobx_value_type_of.d.ts +11 -0
  65. package/.out/types/mobx_value_type_of.js +2 -0
  66. package/.out/types/partial_type_def_of.d.ts +40 -0
  67. package/.out/types/partial_type_def_of.js +1 -0
  68. package/.out/types/readonly_type_def_of.d.ts +29 -0
  69. package/.out/types/readonly_type_def_of.js +1 -0
  70. package/.out/types/specs/builder.tests.d.ts +1 -0
  71. package/.out/types/specs/builder.tests.js +93 -0
  72. package/.out/types/specs/flattened_accessors_of.tests.d.ts +1 -0
  73. package/.out/types/specs/flattened_accessors_of.tests.js +11 -0
  74. package/.out/types/specs/flattened_type_defs_of.tests.d.ts +1 -0
  75. package/.out/types/specs/flattened_type_defs_of.tests.js +71 -0
  76. package/.out/types/specs/flattened_value_types_of.tests.d.ts +1 -0
  77. package/.out/types/specs/flattened_value_types_of.tests.js +11 -0
  78. package/.out/types/specs/json_paths_of.tests.d.ts +1 -0
  79. package/.out/types/specs/json_paths_of.tests.js +199 -0
  80. package/.out/types/specs/partial_type_def_of.tests.d.ts +1 -0
  81. package/.out/types/specs/partial_type_def_of.tests.js +50 -0
  82. package/.out/types/specs/readonly_type_def_of.tests.d.ts +1 -0
  83. package/.out/types/specs/readonly_type_def_of.tests.js +55 -0
  84. package/.out/types/specs/strict_definitions.tests.d.ts +1 -0
  85. package/.out/types/specs/strict_definitions.tests.js +42 -0
  86. package/.out/types/specs/value_to_type_paths_of.tests.d.ts +1 -0
  87. package/.out/types/specs/value_to_type_paths_of.tests.js +90 -0
  88. package/.out/types/specs/value_type_of.tests.d.ts +1 -0
  89. package/.out/types/specs/value_type_of.tests.js +91 -0
  90. package/.out/types/specs/value_types_of_discriminated_union.tests.d.ts +1 -0
  91. package/.out/types/specs/value_types_of_discriminated_union.tests.js +9 -0
  92. package/.out/types/strict_definitions.d.ts +44 -0
  93. package/.out/types/strict_definitions.js +1 -0
  94. package/.out/types/value_to_type_paths_of.d.ts +22 -0
  95. package/.out/types/value_to_type_paths_of.js +1 -0
  96. package/.out/types/value_type_of.d.ts +24 -0
  97. package/.out/types/value_type_of.js +1 -0
  98. package/.out/types/value_types_of_discriminated_union.d.ts +9 -0
  99. package/.out/types/value_types_of_discriminated_union.js +1 -0
  100. package/.out/vitest.workspace.d.ts +2 -0
  101. package/.out/vitest.workspace.js +7 -0
  102. package/.turbo/turbo-build.log +18 -0
  103. package/.turbo/turbo-check-types.log +3 -0
  104. package/.turbo/turbo-release$colon$exports.log +3 -0
  105. package/README.md +12 -0
  106. package/dist/index.cjs +798 -0
  107. package/dist/index.d.cts +301 -0
  108. package/dist/index.d.ts +301 -0
  109. package/dist/index.js +775 -0
  110. package/index.ts +20 -0
  111. package/package.exports.json +18 -0
  112. package/package.json +45 -0
  113. package/transformers/copies/copy.ts +18 -0
  114. package/transformers/copies/copy_to.ts +226 -0
  115. package/transformers/copies/mobx_copy.ts +81 -0
  116. package/transformers/copies/specs/copy_to.tests.ts +143 -0
  117. package/transformers/copies/specs/mobx_copy.tests.ts +26 -0
  118. package/transformers/flatteners/flatten_accessors_of.ts +43 -0
  119. package/transformers/flatteners/flatten_json_value_to_type_paths_of.ts +39 -0
  120. package/transformers/flatteners/flatten_type_def_to.ts +127 -0
  121. package/transformers/flatteners/flatten_type_defs_of.ts +16 -0
  122. package/transformers/flatteners/flatten_value_type_to.ts +227 -0
  123. package/transformers/flatteners/flatten_value_types_of.ts +23 -0
  124. package/transformers/flatteners/json_path.ts +15 -0
  125. package/transformers/flatteners/specs/flatten_accessors_of.tests.ts +113 -0
  126. package/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.ts +115 -0
  127. package/transformers/flatteners/specs/flatten_type_def_to.tests.ts +146 -0
  128. package/transformers/flatteners/specs/flatten_type_defs_of.tests.ts +26 -0
  129. package/transformers/flatteners/specs/flatten_value_type_to.tests.ts +452 -0
  130. package/transformers/flatteners/specs/flatten_value_types_of.tests.ts +46 -0
  131. package/transformers/flatteners/specs/value_path_to_type_path.tests.ts +240 -0
  132. package/transformers/flatteners/value_path_to_type_path.ts +164 -0
  133. package/tsconfig.build.json +11 -0
  134. package/tsconfig.json +15 -0
  135. package/tsup.config.ts +16 -0
  136. package/types/builders.ts +284 -0
  137. package/types/definitions.ts +106 -0
  138. package/types/flattened.ts +5 -0
  139. package/types/flattened_accessors_of.ts +15 -0
  140. package/types/flattened_type_defs_of.ts +130 -0
  141. package/types/flattened_value_types_of.ts +11 -0
  142. package/types/json_path_of.ts +7 -0
  143. package/types/json_paths_of.ts +129 -0
  144. package/types/mobx_value_type_of.ts +16 -0
  145. package/types/partial_type_def_of.ts +64 -0
  146. package/types/readonly_type_def_of.ts +53 -0
  147. package/types/specs/builder.tests.ts +295 -0
  148. package/types/specs/flattened_accessors_of.tests.ts +27 -0
  149. package/types/specs/flattened_type_defs_of.tests.ts +212 -0
  150. package/types/specs/flattened_value_types_of.tests.ts +21 -0
  151. package/types/specs/json_paths_of.tests.ts +304 -0
  152. package/types/specs/partial_type_def_of.tests.ts +251 -0
  153. package/types/specs/readonly_type_def_of.tests.ts +158 -0
  154. package/types/specs/strict_definitions.tests.ts +184 -0
  155. package/types/specs/value_to_type_paths_of.tests.ts +181 -0
  156. package/types/specs/value_type_of.tests.ts +329 -0
  157. package/types/specs/value_types_of_discriminated_union.tests.ts +30 -0
  158. package/types/strict_definitions.ts +107 -0
  159. package/types/value_to_type_paths_of.ts +184 -0
  160. package/types/value_type_of.ts +84 -0
  161. package/types/value_types_of_discriminated_union.ts +14 -0
  162. package/vitest.workspace.ts +11 -0
package/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ export * from './transformers/copies/copy'
2
+ export * from './transformers/copies/mobx_copy'
3
+ export * from './transformers/flatteners/flatten_accessors_of'
4
+ export * from './transformers/flatteners/flatten_json_value_to_type_paths_of'
5
+ export * from './transformers/flatteners/flatten_type_defs_of'
6
+ export * from './transformers/flatteners/flatten_value_type_to'
7
+ export * from './transformers/flatteners/json_path'
8
+ export * from './transformers/flatteners/value_path_to_type_path'
9
+ export * from './types/builders'
10
+ export * from './types/definitions'
11
+ export * from './types/flattened_accessors_of'
12
+ export * from './types/flattened_type_defs_of'
13
+ export * from './types/flattened_value_types_of'
14
+ export * from './types/json_paths_of'
15
+ export * from './types/mobx_value_type_of'
16
+ export * from './types/readonly_type_def_of'
17
+ export * from './types/strict_definitions'
18
+ export * from './types/value_to_type_paths_of'
19
+ export * from './types/value_type_of'
20
+ export * from './types/value_types_of_discriminated_union'
@@ -0,0 +1,18 @@
1
+ {
2
+ "exports": {
3
+ ".": {
4
+ "import": {
5
+ "types": "./dist/index.d.ts",
6
+
7
+ "default": "./dist/index.js"
8
+ },
9
+ "require": {
10
+ "types": "./dist/index.d.cts",
11
+
12
+ "default": "./dist/index.cjs"
13
+ }
14
+ }
15
+ },
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "dependencies": {
3
+ "@strictly/base": "*",
4
+ "mobx": "^6.13.5"
5
+ },
6
+ "devDependencies": {
7
+ "@strictly/support-vite": "*"
8
+ },
9
+ "license": "MIT",
10
+ "name": "@strictly/define",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "repository": {
15
+ "directory": "packages/define",
16
+ "type": "git",
17
+ "url": "git+https://github.com/madmaw/de.git"
18
+ },
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "check-types": "tsc",
22
+ "clean": "del-cli dist",
23
+ "lint": "cross-env ESLINT_USE_FLAT_CONFIG=false eslint . --max-warnings=0",
24
+ "lint:fix": "cross-env ESLINT_USE_FLAT_CONFIG=false eslint . --fix",
25
+ "release:exports": "json -f package.json -f package.exports.json --merge > package.release.json",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest"
28
+ },
29
+ "type": "module",
30
+ "version": "0.0.1",
31
+ "exports": {
32
+ ".": {
33
+ "import": {
34
+ "types": "./dist/index.d.ts",
35
+ "default": "./dist/index.js"
36
+ },
37
+ "require": {
38
+ "types": "./dist/index.d.cts",
39
+ "default": "./dist/index.cjs"
40
+ }
41
+ }
42
+ },
43
+ "main": "./dist/index.js",
44
+ "types": "./dist/index.d.ts"
45
+ }
@@ -0,0 +1,18 @@
1
+ import { type ReadonlyTypeDefOf } from 'types/readonly_type_def_of'
2
+ import { type StrictType } from 'types/strict_definitions'
3
+ import { type ValueTypeOf } from 'types/value_type_of'
4
+ import {
5
+ type AnyValueType,
6
+ copyTo,
7
+ } from './copy_to'
8
+
9
+ function identity(v: AnyValueType): AnyValueType {
10
+ return v
11
+ }
12
+
13
+ export function copy<T extends StrictType>(
14
+ t: T,
15
+ proto: ValueTypeOf<ReadonlyTypeDefOf<T>>,
16
+ ): ValueTypeOf<T> {
17
+ return copyTo(t, proto, identity)
18
+ }
@@ -0,0 +1,226 @@
1
+ import {
2
+ map,
3
+ reduce,
4
+ UnexpectedImplementationError,
5
+ UnreachableError,
6
+ } from '@strictly/base'
7
+ import {
8
+ type ObjectFieldKey,
9
+ type TypeDef,
10
+ TypeDefType,
11
+ type UnionKey,
12
+ } from 'types/definitions'
13
+ import { type ReadonlyTypeDefOf } from 'types/readonly_type_def_of'
14
+ import {
15
+ type StrictListTypeDef,
16
+ type StrictLiteralTypeDef,
17
+ type StrictObjectTypeDef,
18
+ type StrictRecordTypeDef,
19
+ type StrictStructuredTypeDefFields,
20
+ type StrictType,
21
+ type StrictTypeDef,
22
+ type StrictUnionTypeDef,
23
+ } from 'types/strict_definitions'
24
+ import { type ValueTypeOf } from 'types/value_type_of'
25
+
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ export type AnyValueType = any
28
+
29
+ export type Copier<R> = (v: AnyValueType, t: StrictTypeDef) => R
30
+
31
+ export function copyTo<
32
+ T extends StrictType,
33
+ R extends ValueTypeOf<ReadonlyTypeDefOf<T>>,
34
+ >(
35
+ { definition }: T,
36
+ value: ValueTypeOf<ReadonlyTypeDefOf<T>>,
37
+ copier: Copier<R>,
38
+ ): R {
39
+ return internalCopyTo(
40
+ definition,
41
+ value,
42
+ copier,
43
+ )
44
+ }
45
+
46
+ /**
47
+ * Creates a copy of the supplied value
48
+ * @param def description of the object to create
49
+ * @param value the value to populate the object from
50
+ * @returns a copy of the supplied value
51
+ */
52
+ function internalCopyTo<R>(
53
+ definition: TypeDef,
54
+ value: AnyValueType,
55
+ copier: Copier<R>,
56
+ ): R {
57
+ switch (definition.type) {
58
+ case TypeDefType.Literal:
59
+ return copyLiteral(
60
+ definition,
61
+ value,
62
+ copier,
63
+ )
64
+ case TypeDefType.List:
65
+ return copyList(
66
+ definition,
67
+ value,
68
+ copier,
69
+ )
70
+ case TypeDefType.Record:
71
+ return copyRecord(
72
+ definition,
73
+ value,
74
+ copier,
75
+ )
76
+ case TypeDefType.Object:
77
+ return copyObject(
78
+ definition,
79
+ value,
80
+ copier,
81
+ )
82
+ case TypeDefType.Union:
83
+ return copyUnion(
84
+ definition,
85
+ value,
86
+ copier,
87
+ )
88
+ default:
89
+ throw new UnreachableError(definition)
90
+ }
91
+ }
92
+
93
+ function copyLiteral<
94
+ R,
95
+ >(
96
+ typeDef: StrictLiteralTypeDef,
97
+ value: ValueTypeOf<{ definition: StrictLiteralTypeDef }>,
98
+ copier: Copier<R>,
99
+ ): R {
100
+ // mutable and immutable literals should be the same type
101
+ return copier(value, typeDef)
102
+ }
103
+
104
+ function copyList<
105
+ R,
106
+ >(
107
+ typeDef: StrictListTypeDef,
108
+ arr: AnyValueType[],
109
+ copier: Copier<R>,
110
+ ): R {
111
+ const {
112
+ elements,
113
+ } = typeDef
114
+ const list = arr.map(function (value) {
115
+ return internalCopyTo(elements, value, copier)
116
+ })
117
+ return copier(
118
+ list,
119
+ typeDef,
120
+ )
121
+ }
122
+
123
+ function copyRecord<
124
+ R,
125
+ >(
126
+ typeDef: StrictRecordTypeDef,
127
+ value: AnyValueType,
128
+ copier: Copier<R>,
129
+ ): R {
130
+ const {
131
+ valueTypeDef,
132
+ } = typeDef
133
+ const record = map(
134
+ value,
135
+ function (_key, value) {
136
+ return internalCopyTo(valueTypeDef, value, copier)
137
+ },
138
+ )
139
+ return copier(
140
+ record,
141
+ typeDef,
142
+ )
143
+ }
144
+
145
+ function copyObjectFields<
146
+ R,
147
+ Extra extends Record<string, UnionKey>,
148
+ >(
149
+ fields: StrictStructuredTypeDefFields,
150
+ value: Record<ObjectFieldKey, AnyValueType>,
151
+ copier: Copier<R>,
152
+ extra: Extra,
153
+ ): Record<ObjectFieldKey, AnyValueType> {
154
+ const record = reduce(fields, function (acc, key, field: TypeDef) {
155
+ const fieldValue = value[key]
156
+ acc[key] = fieldValue != null
157
+ ? internalCopyTo(field, fieldValue, copier)
158
+ : fieldValue
159
+ return acc
160
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
161
+ }, extra as Record<string | number | symbol, AnyValueType>)
162
+ return record
163
+ }
164
+
165
+ function copyObject<
166
+ R,
167
+ >(
168
+ typeDef: StrictObjectTypeDef,
169
+ value: AnyValueType,
170
+ copier: Copier<R>,
171
+ ): R {
172
+ const {
173
+ fields,
174
+ } = typeDef
175
+ const record = copyObjectFields(fields, value, copier, {})
176
+ return copier(record, typeDef)
177
+ }
178
+
179
+ function copyUnion<
180
+ R,
181
+ >(
182
+ typeDef: StrictUnionTypeDef,
183
+ value: AnyValueType,
184
+ copier: Copier<R>,
185
+ ): R {
186
+ const {
187
+ discriminator,
188
+ unions,
189
+ } = typeDef
190
+
191
+ // is it a discriminated union with a struct?
192
+ if (discriminator != null) {
193
+ const discriminatorValue = value[discriminator]
194
+ const discriminatingUnion = {
195
+ ...internalCopyTo(
196
+ unions[discriminatorValue],
197
+ value,
198
+ copier,
199
+ ),
200
+ [discriminator]: discriminatorValue,
201
+ }
202
+ return copier(discriminatingUnion, typeDef)
203
+ }
204
+
205
+ // is it a `<constant1> | <constant2> | X`? We can handle that
206
+ // a good example is when we `| null` something
207
+ const allTypeDefs = Object.values<TypeDef>(unions)
208
+ const variableTypeDefs = allTypeDefs.filter(function (typeDef: TypeDef) {
209
+ return typeDef.type !== TypeDefType.Literal || typeDef.valuePrototype == null
210
+ })
211
+ if (variableTypeDefs.length <= 1) {
212
+ // can handle up to one non-constant value
213
+ const targetTypeDef = allTypeDefs.find(function (typeDef) {
214
+ return typeDef.type === TypeDefType.Literal
215
+ && typeDef.valuePrototype != null
216
+ && typeDef.valuePrototype.indexOf(value) >= 0
217
+ }) || variableTypeDefs[0]
218
+ return internalCopyTo(targetTypeDef, value, copier)
219
+ }
220
+
221
+ // oh dear!
222
+ // this should have caused a type error already
223
+ throw new UnexpectedImplementationError(
224
+ 'unions must be strict in order to be copied',
225
+ )
226
+ }
@@ -0,0 +1,81 @@
1
+ import {
2
+ reduce,
3
+ UnreachableError,
4
+ } from '@strictly/base'
5
+ import {
6
+ type IObservableFactory,
7
+ makeObservable,
8
+ observable,
9
+ } from 'mobx'
10
+ import { getUnionTypeDef } from 'transformers/flatteners/flatten_value_type_to'
11
+ import {
12
+ type ObjectFieldKey,
13
+ TypeDefType,
14
+ } from 'types/definitions'
15
+ import { type MobxValueTypeOf } from 'types/mobx_value_type_of'
16
+ import { type ReadonlyTypeDefOf } from 'types/readonly_type_def_of'
17
+ import {
18
+ type StrictType,
19
+ type StrictTypeDef,
20
+ } from 'types/strict_definitions'
21
+ import { type ValueTypeOf } from 'types/value_type_of'
22
+ import {
23
+ type AnyValueType,
24
+ copyTo,
25
+ } from './copy_to'
26
+
27
+ function observeValue(
28
+ v: AnyValueType,
29
+ def: StrictTypeDef,
30
+ ): AnyValueType {
31
+ if (v == null) {
32
+ return v
33
+ }
34
+ switch (def.type) {
35
+ case TypeDefType.Literal:
36
+ return v
37
+ case TypeDefType.List:
38
+ // can't work out that an observable array is an array
39
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
40
+ return observable.array(v as any[], { deep: false }) as any
41
+ case TypeDefType.Record:
42
+ // observable observes all fields
43
+ return observable(
44
+ v,
45
+ {},
46
+ {
47
+ deep: false,
48
+ },
49
+ )
50
+ case TypeDefType.Object:
51
+ // `makeObservable` only observes the specified props
52
+ return makeObservable(
53
+ v,
54
+ reduce(
55
+ def.fields,
56
+ function (acc, k) {
57
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
58
+ acc[k as ObjectFieldKey] = observable
59
+ return acc
60
+ },
61
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62
+ {} as Record<ObjectFieldKey, IObservableFactory>,
63
+ ),
64
+ {
65
+ deep: false,
66
+ },
67
+ )
68
+ case TypeDefType.Union:
69
+ // delegate to the underlying value
70
+ return observeValue(v, getUnionTypeDef(def, v))
71
+ default:
72
+ throw new UnreachableError(def)
73
+ }
74
+ }
75
+
76
+ export function mobxCopy<T extends StrictType>(
77
+ t: T,
78
+ proto: ValueTypeOf<ReadonlyTypeDefOf<T>>,
79
+ ): MobxValueTypeOf<T> {
80
+ return copyTo(t, proto, observeValue)
81
+ }
@@ -0,0 +1,143 @@
1
+ import {
2
+ type AnyValueType,
3
+ copyTo,
4
+ } from 'transformers/copies/copy_to'
5
+ import {
6
+ booleanType,
7
+ list,
8
+ literal,
9
+ numberType,
10
+ object,
11
+ record,
12
+ stringType,
13
+ union,
14
+ } from 'types/builders'
15
+ import { TypeDefType } from 'types/definitions'
16
+ import { type StrictTypeDef } from 'types/strict_definitions'
17
+
18
+ describe('copyTo', function () {
19
+ function toString(v: AnyValueType, t: StrictTypeDef) {
20
+ if (t.type === TypeDefType.Literal) {
21
+ return JSON.stringify(v)
22
+ } else {
23
+ return v
24
+ }
25
+ }
26
+
27
+ describe('literal', function () {
28
+ const type = literal<1>()
29
+ it('copies', function () {
30
+ const c = copyTo(type, 1, toString)
31
+ expect(c).toEqual('1')
32
+ })
33
+ })
34
+
35
+ describe('list', function () {
36
+ const typeDef = list(literal<number>())
37
+ it('copies', function () {
38
+ const c = copyTo(
39
+ typeDef,
40
+ [
41
+ 1,
42
+ 2,
43
+ 3,
44
+ ],
45
+ toString,
46
+ )
47
+ expect(c).toEqual([
48
+ '1',
49
+ '2',
50
+ '3',
51
+ ])
52
+ })
53
+ })
54
+
55
+ describe('record', function () {
56
+ const typeDef = record<typeof numberType, 'a' | 'b'>(numberType)
57
+ it('copies', function () {
58
+ const c = copyTo(
59
+ typeDef,
60
+ {
61
+ a: 1,
62
+ b: 2,
63
+ },
64
+ toString,
65
+ )
66
+ expect(c).toEqual({
67
+ a: '1',
68
+ b: '2',
69
+ })
70
+ })
71
+ })
72
+
73
+ describe('object', function () {
74
+ const typeDef = object()
75
+ .set('a', numberType)
76
+ .set('b', booleanType)
77
+ .set('c', stringType)
78
+ it('copies', function () {
79
+ const c = copyTo(
80
+ typeDef,
81
+ {
82
+ a: 1,
83
+ b: true,
84
+ c: 'a',
85
+ },
86
+ toString,
87
+ )
88
+ expect(c).toEqual({
89
+ a: '1',
90
+ b: 'true',
91
+ c: '"a"',
92
+ })
93
+ })
94
+ })
95
+
96
+ describe('union', function () {
97
+ describe('non-discriminated', function () {
98
+ const typeDef = union()
99
+ .add('0', list(numberType))
100
+ .add('1', literal(['b']))
101
+ .add('2', literal([false]))
102
+ it('copies string literal', function () {
103
+ const c = copyTo(
104
+ typeDef,
105
+ 'b',
106
+ toString,
107
+ )
108
+ expect(c).toEqual('"b"')
109
+ })
110
+
111
+ it('copies boolean literal', function () {
112
+ const c = copyTo(
113
+ typeDef,
114
+ false,
115
+ toString,
116
+ )
117
+ expect(c).toEqual('false')
118
+ })
119
+ })
120
+
121
+ describe('discriminated', function () {
122
+ const typeDef = union('d')
123
+ .add('a', object().set('x', numberType))
124
+ .add('b', object().set('y', booleanType))
125
+
126
+ it('copies', function () {
127
+ const c = copyTo(
128
+ typeDef,
129
+ {
130
+ d: 'a',
131
+ x: 1,
132
+ },
133
+ toString,
134
+ )
135
+
136
+ expect(c).toEqual({
137
+ d: 'a',
138
+ x: '1',
139
+ })
140
+ })
141
+ })
142
+ })
143
+ })
@@ -0,0 +1,26 @@
1
+ import { mobxCopy } from 'transformers/copies/mobx_copy'
2
+ import {
3
+ numberType,
4
+ object,
5
+ } from 'types/builders'
6
+ import { type ValueTypeOf } from 'types/value_type_of'
7
+
8
+ describe('mobxCopy', function () {
9
+ describe('object', function () {
10
+ describe('optional field', function () {
11
+ const type = object().setOptional('n', numberType)
12
+ type T = ValueTypeOf<typeof type>
13
+ it('copies unpopulated', function () {
14
+ const v: T = {}
15
+ const c = mobxCopy(type, v)
16
+ expect(c).toEqual(v)
17
+ })
18
+
19
+ it('copies populated', function () {
20
+ const v: T = { n: 1 }
21
+ const c = mobxCopy(type, v)
22
+ expect(c).toEqual(v)
23
+ })
24
+ })
25
+ })
26
+ })
@@ -0,0 +1,43 @@
1
+ import {
2
+ type Type,
3
+ type TypeDef,
4
+ } from 'types/definitions'
5
+ import {
6
+ type Accessor,
7
+ type FlattenedAccessorsOf,
8
+ } from 'types/flattened_accessors_of'
9
+ import { type ValueTypeOf } from 'types/value_type_of'
10
+ import {
11
+ type AnyValueType,
12
+ flattenValueTypeTo,
13
+ type Setter,
14
+ } from './flatten_value_type_to'
15
+
16
+ function mapAccessor(
17
+ _t: TypeDef,
18
+ value: AnyValueType,
19
+ set: Setter<AnyValueType>,
20
+ ): Accessor<AnyValueType> {
21
+ return {
22
+ value,
23
+ set,
24
+ }
25
+ }
26
+
27
+ export function flattenAccessorsOf<
28
+ T extends Type,
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ R extends Readonly<Record<string, Accessor<any>>> = FlattenedAccessorsOf<T>,
31
+ >(
32
+ t: T,
33
+ value: ValueTypeOf<T>,
34
+ setValue: Setter<ValueTypeOf<T>>,
35
+ ): R {
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ return flattenValueTypeTo<T, Accessor<any>, R>(
38
+ t,
39
+ value,
40
+ setValue,
41
+ mapAccessor,
42
+ )
43
+ }
@@ -0,0 +1,39 @@
1
+ import {
2
+ type Type,
3
+ type TypeDef,
4
+ } from 'types/definitions'
5
+ import { type ValueTypeOf } from 'types/value_type_of'
6
+ import {
7
+ type AnyValueType,
8
+ flattenValueTypeTo,
9
+ type Setter,
10
+ } from './flatten_value_type_to'
11
+
12
+ function mapTypePaths(
13
+ _t: TypeDef,
14
+ _value: AnyValueType,
15
+ _set: Setter<AnyValueType>,
16
+ typePath: string,
17
+ ) {
18
+ return typePath
19
+ }
20
+
21
+ export function flattenJsonValueToTypePathsOf<
22
+ T extends Type,
23
+ R extends Record<string, string | number | symbol>,
24
+ >(
25
+ t: T,
26
+ value: ValueTypeOf<T>,
27
+ // TODO
28
+ // : FlattenedJsonValueToTypePathsOf<T>
29
+ ): R {
30
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
31
+ return flattenValueTypeTo(
32
+ t,
33
+ value,
34
+ function () {
35
+ // do nothing
36
+ },
37
+ mapTypePaths,
38
+ ) as R
39
+ }