1
1
import { JsonApiResource , ModelForType , SchemaCollection } from './types' ;
2
-
3
- type PartialJsonApiResource < T extends JsonApiResource > = {
4
- [ P in keyof T ] ?: Partial < T [ P ] > ;
5
- } ;
2
+ import { Store } from './store.ts' ;
6
3
7
4
class ModelBase < Schema extends JsonApiResource = JsonApiResource > {
8
5
public type : Schema [ 'type' ] ;
@@ -12,7 +9,10 @@ class ModelBase<Schema extends JsonApiResource = JsonApiResource> {
12
9
public meta : Schema [ 'meta' ] = { } ;
13
10
public links : Schema [ 'links' ] = { } ;
14
11
15
- constructor ( data : Schema ) {
12
+ constructor (
13
+ data : Schema ,
14
+ protected store : Store ,
15
+ ) {
16
16
this . type = data . type ;
17
17
this . id = data . id ;
18
18
@@ -32,23 +32,73 @@ class ModelBase<Schema extends JsonApiResource = JsonApiResource> {
32
32
/**
33
33
* Merge new JSON:API resource data into the model.
34
34
*/
35
- public merge ( data : PartialJsonApiResource < Schema > ) : void {
35
+ public merge (
36
+ data : Omit < JsonApiResource < Schema [ 'type' ] > , 'type' | 'id' > ,
37
+ ) : void {
36
38
this . links = data . links ?? this . links ;
37
39
this . meta = data . meta ?? this . meta ;
38
40
39
41
if ( data . attributes ) {
40
42
Object . assign ( this . attributes , data . attributes ) ;
43
+
44
+ Object . keys ( data . attributes ) . forEach ( ( name ) => {
45
+ if (
46
+ Object . getOwnPropertyDescriptor (
47
+ Object . getPrototypeOf ( this ) ,
48
+ name ,
49
+ ) ||
50
+ Object . getOwnPropertyDescriptor ( this , name )
51
+ ) {
52
+ return ;
53
+ }
54
+
55
+ Object . defineProperty ( this , name , {
56
+ get : ( ) => this . attributes [ name ] ,
57
+ configurable : true ,
58
+ enumerable : true ,
59
+ } ) ;
60
+ } ) ;
41
61
}
42
62
43
63
if ( data . relationships ) {
44
64
Object . entries ( data . relationships ) . forEach (
45
65
( [ name , relationship ] ) => {
46
66
this . relationships [ name ] = this . relationships [ name ] || { } ;
67
+
47
68
Object . assign ( this . relationships [ name ] , relationship ) ;
69
+
70
+ if (
71
+ Object . getOwnPropertyDescriptor (
72
+ Object . getPrototypeOf ( this ) ,
73
+ name ,
74
+ ) ||
75
+ Object . getOwnPropertyDescriptor ( this , name )
76
+ ) {
77
+ return ;
78
+ }
79
+
80
+ Object . defineProperty ( this , name , {
81
+ get : ( ) => this . getRelationship ( name ) ,
82
+ configurable : true ,
83
+ enumerable : true ,
84
+ } ) ;
48
85
} ,
49
86
) ;
50
87
}
51
88
}
89
+
90
+ private getRelationship ( name : string ) {
91
+ const data = this . relationships [ name ] . data ;
92
+
93
+ // https://github.com/microsoft/TypeScript/issues/14107
94
+ if ( Array . isArray ( data ) ) {
95
+ return this . store . find ( data ) ;
96
+ }
97
+
98
+ if ( data ) {
99
+ return this . store . find ( data ) ;
100
+ }
101
+ }
52
102
}
53
103
54
104
type ProxiedModel <
@@ -79,4 +129,5 @@ export const Model: new <
79
129
Schemas extends SchemaCollection = SchemaCollection ,
80
130
> (
81
131
data : JsonApiResource < Schema [ 'type' ] > ,
132
+ store : Store < Schemas > ,
82
133
) => Model < Schema , Schemas > = ModelBase as any ;
0 commit comments