@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.
- package/.eslintrc.cjs +31 -0
- package/.out/index.d.ts +20 -0
- package/.out/index.js +20 -0
- package/.out/transformers/copies/copy.d.ts +4 -0
- package/.out/transformers/copies/copy.js +7 -0
- package/.out/transformers/copies/copy_to.d.ts +6 -0
- package/.out/transformers/copies/copy_to.js +91 -0
- package/.out/transformers/copies/mobx_copy.d.ts +5 -0
- package/.out/transformers/copies/mobx_copy.js +42 -0
- package/.out/transformers/copies/specs/copy_to.tests.d.ts +1 -0
- package/.out/transformers/copies/specs/copy_to.tests.js +97 -0
- package/.out/transformers/copies/specs/mobx_copy.tests.d.ts +1 -0
- package/.out/transformers/copies/specs/mobx_copy.tests.js +19 -0
- package/.out/transformers/flatteners/flatten_accessors_of.d.ts +5 -0
- package/.out/transformers/flatteners/flatten_accessors_of.js +11 -0
- package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.d.ts +3 -0
- package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.js +10 -0
- package/.out/transformers/flatteners/flatten_type_def_to.d.ts +4 -0
- package/.out/transformers/flatteners/flatten_type_def_to.js +49 -0
- package/.out/transformers/flatteners/flatten_type_defs_of.d.ts +3 -0
- package/.out/transformers/flatteners/flatten_type_defs_of.js +7 -0
- package/.out/transformers/flatteners/flatten_value_type_to.d.ts +11 -0
- package/.out/transformers/flatteners/flatten_value_type_to.js +79 -0
- package/.out/transformers/flatteners/flatten_value_types_of.d.ts +3 -0
- package/.out/transformers/flatteners/flatten_value_types_of.js +7 -0
- package/.out/transformers/flatteners/json_path.d.ts +2 -0
- package/.out/transformers/flatteners/json_path.js +14 -0
- package/.out/transformers/flatteners/specs/flatten_accessors_of.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_accessors_of.tests.js +90 -0
- package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.js +94 -0
- package/.out/transformers/flatteners/specs/flatten_type_def_to.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_type_def_to.tests.js +110 -0
- package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.js +17 -0
- package/.out/transformers/flatteners/specs/flatten_value_type_to.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_value_type_to.tests.js +297 -0
- package/.out/transformers/flatteners/specs/flatten_value_types_of.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/flatten_value_types_of.tests.js +37 -0
- package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.d.ts +1 -0
- package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.js +167 -0
- package/.out/transformers/flatteners/value_path_to_type_path.d.ts +2 -0
- package/.out/transformers/flatteners/value_path_to_type_path.js +96 -0
- package/.out/tsconfig.json +15 -0
- package/.out/tsconfig.tsbuildinfo +1 -0
- package/.out/tsup.config.d.ts +3 -0
- package/.out/tsup.config.js +12 -0
- package/.out/types/builders.d.ts +62 -0
- package/.out/types/builders.js +148 -0
- package/.out/types/definitions.d.ts +41 -0
- package/.out/types/definitions.js +26 -0
- package/.out/types/flattened.d.ts +2 -0
- package/.out/types/flattened.js +1 -0
- package/.out/types/flattened_accessors_of.d.ts +9 -0
- package/.out/types/flattened_accessors_of.js +1 -0
- package/.out/types/flattened_type_defs_of.d.ts +21 -0
- package/.out/types/flattened_type_defs_of.js +1 -0
- package/.out/types/flattened_value_types_of.d.ts +6 -0
- package/.out/types/flattened_value_types_of.js +1 -0
- package/.out/types/json_path_of.d.ts +1 -0
- package/.out/types/json_path_of.js +1 -0
- package/.out/types/json_paths_of.d.ts +16 -0
- package/.out/types/json_paths_of.js +1 -0
- package/.out/types/mobx_value_type_of.d.ts +11 -0
- package/.out/types/mobx_value_type_of.js +2 -0
- package/.out/types/partial_type_def_of.d.ts +40 -0
- package/.out/types/partial_type_def_of.js +1 -0
- package/.out/types/readonly_type_def_of.d.ts +29 -0
- package/.out/types/readonly_type_def_of.js +1 -0
- package/.out/types/specs/builder.tests.d.ts +1 -0
- package/.out/types/specs/builder.tests.js +93 -0
- package/.out/types/specs/flattened_accessors_of.tests.d.ts +1 -0
- package/.out/types/specs/flattened_accessors_of.tests.js +11 -0
- package/.out/types/specs/flattened_type_defs_of.tests.d.ts +1 -0
- package/.out/types/specs/flattened_type_defs_of.tests.js +71 -0
- package/.out/types/specs/flattened_value_types_of.tests.d.ts +1 -0
- package/.out/types/specs/flattened_value_types_of.tests.js +11 -0
- package/.out/types/specs/json_paths_of.tests.d.ts +1 -0
- package/.out/types/specs/json_paths_of.tests.js +199 -0
- package/.out/types/specs/partial_type_def_of.tests.d.ts +1 -0
- package/.out/types/specs/partial_type_def_of.tests.js +50 -0
- package/.out/types/specs/readonly_type_def_of.tests.d.ts +1 -0
- package/.out/types/specs/readonly_type_def_of.tests.js +55 -0
- package/.out/types/specs/strict_definitions.tests.d.ts +1 -0
- package/.out/types/specs/strict_definitions.tests.js +42 -0
- package/.out/types/specs/value_to_type_paths_of.tests.d.ts +1 -0
- package/.out/types/specs/value_to_type_paths_of.tests.js +90 -0
- package/.out/types/specs/value_type_of.tests.d.ts +1 -0
- package/.out/types/specs/value_type_of.tests.js +91 -0
- package/.out/types/specs/value_types_of_discriminated_union.tests.d.ts +1 -0
- package/.out/types/specs/value_types_of_discriminated_union.tests.js +9 -0
- package/.out/types/strict_definitions.d.ts +44 -0
- package/.out/types/strict_definitions.js +1 -0
- package/.out/types/value_to_type_paths_of.d.ts +22 -0
- package/.out/types/value_to_type_paths_of.js +1 -0
- package/.out/types/value_type_of.d.ts +24 -0
- package/.out/types/value_type_of.js +1 -0
- package/.out/types/value_types_of_discriminated_union.d.ts +9 -0
- package/.out/types/value_types_of_discriminated_union.js +1 -0
- package/.out/vitest.workspace.d.ts +2 -0
- package/.out/vitest.workspace.js +7 -0
- package/.turbo/turbo-build.log +18 -0
- package/.turbo/turbo-check-types.log +3 -0
- package/.turbo/turbo-release$colon$exports.log +3 -0
- package/README.md +12 -0
- package/dist/index.cjs +798 -0
- package/dist/index.d.cts +301 -0
- package/dist/index.d.ts +301 -0
- package/dist/index.js +775 -0
- package/index.ts +20 -0
- package/package.exports.json +18 -0
- package/package.json +45 -0
- package/transformers/copies/copy.ts +18 -0
- package/transformers/copies/copy_to.ts +226 -0
- package/transformers/copies/mobx_copy.ts +81 -0
- package/transformers/copies/specs/copy_to.tests.ts +143 -0
- package/transformers/copies/specs/mobx_copy.tests.ts +26 -0
- package/transformers/flatteners/flatten_accessors_of.ts +43 -0
- package/transformers/flatteners/flatten_json_value_to_type_paths_of.ts +39 -0
- package/transformers/flatteners/flatten_type_def_to.ts +127 -0
- package/transformers/flatteners/flatten_type_defs_of.ts +16 -0
- package/transformers/flatteners/flatten_value_type_to.ts +227 -0
- package/transformers/flatteners/flatten_value_types_of.ts +23 -0
- package/transformers/flatteners/json_path.ts +15 -0
- package/transformers/flatteners/specs/flatten_accessors_of.tests.ts +113 -0
- package/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.ts +115 -0
- package/transformers/flatteners/specs/flatten_type_def_to.tests.ts +146 -0
- package/transformers/flatteners/specs/flatten_type_defs_of.tests.ts +26 -0
- package/transformers/flatteners/specs/flatten_value_type_to.tests.ts +452 -0
- package/transformers/flatteners/specs/flatten_value_types_of.tests.ts +46 -0
- package/transformers/flatteners/specs/value_path_to_type_path.tests.ts +240 -0
- package/transformers/flatteners/value_path_to_type_path.ts +164 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +15 -0
- package/tsup.config.ts +16 -0
- package/types/builders.ts +284 -0
- package/types/definitions.ts +106 -0
- package/types/flattened.ts +5 -0
- package/types/flattened_accessors_of.ts +15 -0
- package/types/flattened_type_defs_of.ts +130 -0
- package/types/flattened_value_types_of.ts +11 -0
- package/types/json_path_of.ts +7 -0
- package/types/json_paths_of.ts +129 -0
- package/types/mobx_value_type_of.ts +16 -0
- package/types/partial_type_def_of.ts +64 -0
- package/types/readonly_type_def_of.ts +53 -0
- package/types/specs/builder.tests.ts +295 -0
- package/types/specs/flattened_accessors_of.tests.ts +27 -0
- package/types/specs/flattened_type_defs_of.tests.ts +212 -0
- package/types/specs/flattened_value_types_of.tests.ts +21 -0
- package/types/specs/json_paths_of.tests.ts +304 -0
- package/types/specs/partial_type_def_of.tests.ts +251 -0
- package/types/specs/readonly_type_def_of.tests.ts +158 -0
- package/types/specs/strict_definitions.tests.ts +184 -0
- package/types/specs/value_to_type_paths_of.tests.ts +181 -0
- package/types/specs/value_type_of.tests.ts +329 -0
- package/types/specs/value_types_of_discriminated_union.tests.ts +30 -0
- package/types/strict_definitions.ts +107 -0
- package/types/value_to_type_paths_of.ts +184 -0
- package/types/value_type_of.ts +84 -0
- package/types/value_types_of_discriminated_union.ts +14 -0
- 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
|
+
}
|