@@ -72,6 +72,17 @@ function isPathMatch(a: string[], b: string[]) {
72
72
return a . length === b . length && a . every ( ( v , i ) => v === b [ i ] ) ;
73
73
}
74
74
75
+ function isNonEnumerableProp ( prop : string | number | symbol ) {
76
+ return (
77
+ prop === 'constructor' ||
78
+ prop === 'prototype' ||
79
+ prop === '__proto__' ||
80
+ prop === 'toString' ||
81
+ prop === 'toJSON' ||
82
+ prop === 'toHTML'
83
+ ) ;
84
+ }
85
+
75
86
const Editables = new WeakMap < SchemaRecord , SchemaRecord > ( ) ;
76
87
export class SchemaRecord {
77
88
declare [ RecordStore ] : Store ;
@@ -124,7 +135,12 @@ export class SchemaRecord {
124
135
125
136
const proxy = new Proxy ( this , {
126
137
ownKeys ( ) {
127
- return Array . from ( fields . keys ( ) ) ;
138
+ const identityKey = identityField ?. name ;
139
+ const keys = Array . from ( fields . keys ( ) ) ;
140
+ if ( identityKey ) {
141
+ keys . unshift ( identityKey ) ;
142
+ }
143
+ return keys ;
128
144
} ,
129
145
130
146
has ( target : SchemaRecord , prop : string | number | symbol ) {
@@ -135,10 +151,17 @@ export class SchemaRecord {
135
151
} ,
136
152
137
153
getOwnPropertyDescriptor ( target , prop ) {
138
- if ( ! fields . has ( prop as string ) ) {
139
- throw new Error ( `No field named ${ String ( prop ) } on ${ identifier . type } ` ) ;
140
- }
141
154
const schemaForField = prop === identityField ?. name ? identityField : fields . get ( prop as string ) ! ;
155
+ assert ( `No field named ${ String ( prop ) } on ${ identifier . type } ` , schemaForField ) ;
156
+
157
+ if ( isNonEnumerableProp ( prop ) ) {
158
+ return {
159
+ writable : false ,
160
+ enumerable : false ,
161
+ configurable : true ,
162
+ } ;
163
+ }
164
+
142
165
switch ( schemaForField . kind ) {
143
166
case 'derived' :
144
167
return {
@@ -248,6 +271,19 @@ export class SchemaRecord {
248
271
249
272
if ( prop === Symbol . toPrimitive ) return ( ) => null ;
250
273
274
+ if ( prop === Symbol . iterator ) {
275
+ let fn = BoundFns . get ( Symbol . iterator ) ;
276
+ if ( ! fn ) {
277
+ fn = function * ( ) {
278
+ for ( const key in receiver ) {
279
+ yield [ key , receiver [ key as keyof typeof receiver ] ] ;
280
+ }
281
+ } ;
282
+ BoundFns . set ( Symbol . iterator , fn ) ;
283
+ }
284
+ return fn ;
285
+ }
286
+
251
287
if ( prop === 'constructor' ) {
252
288
return SchemaRecord ;
253
289
}
0 commit comments