17
17
* under the License.
18
18
*/
19
19
20
- import { InternalSerializerType } from "./type" ;
20
+ import { FuryClsInfoSymbol , InternalSerializerType , ObjectFuryClsInfo } from "./type" ;
21
21
22
22
export interface TypeDescription {
23
23
type : InternalSerializerType ;
@@ -28,6 +28,7 @@ export interface ObjectTypeDescription extends TypeDescription {
28
28
options : {
29
29
props : { [ key : string ] : TypeDescription } ;
30
30
tag : string ;
31
+ withConstructor ?: false ;
31
32
} ;
32
33
}
33
34
@@ -274,181 +275,234 @@ export type ResultType<T> = T extends {
274
275
type : InternalSerializerType . ONEOF ;
275
276
} ? OneofResult < T > : unknown ;
276
277
278
+ type DecorationWithDescription < T > = ( ( target : any , key ?: string | { name ?: string } ) => void ) & T ;
279
+
280
+ const makeDescriptionWithDecoration = < T extends TypeDescription > ( description : T ) : DecorationWithDescription < T > => {
281
+ function decoration ( target : any , key ?: string | { name ?: string } ) {
282
+ if ( key === undefined ) {
283
+ initMeta ( target , description as unknown as ObjectTypeDescription ) ;
284
+ } else {
285
+ const keyString = typeof key === "string" ? key : key ?. name ;
286
+ if ( ! keyString ) {
287
+ throw new Error ( "Decorators can only be placed on classes and fields" ) ;
288
+ }
289
+ addField ( target . constructor , keyString , description ) ;
290
+ }
291
+ }
292
+ decoration . toJSON = function ( ) {
293
+ return JSON . stringify ( description ) ;
294
+ } ;
295
+ Object . entries ( description ) . map ( ( [ key , value ] : any ) => {
296
+ Object . defineProperty ( decoration , key , {
297
+ enumerable : true ,
298
+ get ( ) {
299
+ return value ;
300
+ } ,
301
+ } ) ;
302
+ } ) ;
303
+ return decoration as unknown as DecorationWithDescription < T > ;
304
+ } ;
305
+
277
306
export const Type = {
278
307
any ( ) {
279
- return {
308
+ return makeDescriptionWithDecoration ( {
280
309
type : InternalSerializerType . ANY as const ,
281
- } ;
310
+ } ) ;
282
311
} ,
283
312
enum < T1 extends { [ key : string ] : any } > ( t1 : T1 ) {
284
- return {
313
+ return makeDescriptionWithDecoration ( {
285
314
type : InternalSerializerType . ENUM as const ,
286
315
options : {
287
316
inner : t1 ,
288
317
} ,
289
- } ;
318
+ } ) ;
290
319
} ,
291
320
oneof < T extends { [ key : string ] : TypeDescription } > ( inner ?: T ) {
292
- return {
321
+ return makeDescriptionWithDecoration ( {
293
322
type : InternalSerializerType . ONEOF as const ,
294
323
options : {
295
324
inner,
296
325
} ,
297
- } ;
326
+ } ) ;
298
327
} ,
299
328
string ( ) {
300
- return {
329
+ return makeDescriptionWithDecoration ( {
301
330
type : InternalSerializerType . STRING as const ,
302
- } ;
331
+ } ) ;
303
332
} ,
304
333
array < T extends TypeDescription > ( def : T ) {
305
- return {
334
+ return makeDescriptionWithDecoration ( {
306
335
type : InternalSerializerType . ARRAY as const ,
307
336
options : {
308
337
inner : def ,
309
338
} ,
310
- } ;
339
+ } ) ;
311
340
} ,
312
341
tuple < T1 extends readonly [ ...readonly TypeDescription [ ] ] > ( t1 : T1 ) {
313
- return {
342
+ return makeDescriptionWithDecoration ( {
314
343
type : InternalSerializerType . TUPLE as const ,
315
344
options : {
316
345
inner : t1 ,
317
346
} ,
318
- } ;
347
+ } ) ;
319
348
} ,
320
349
map < T1 extends TypeDescription , T2 extends TypeDescription > (
321
350
key : T1 ,
322
351
value : T2
323
352
) {
324
- return {
353
+ return makeDescriptionWithDecoration ( {
325
354
type : InternalSerializerType . MAP as const ,
326
355
options : {
327
356
key,
328
357
value,
329
358
} ,
330
- } ;
359
+ } ) ;
331
360
} ,
332
361
set < T extends TypeDescription > ( key : T ) {
333
- return {
362
+ return makeDescriptionWithDecoration ( {
334
363
type : InternalSerializerType . SET as const ,
335
364
options : {
336
365
key,
337
366
} ,
338
- } ;
367
+ } ) ;
339
368
} ,
340
369
bool ( ) {
341
- return {
370
+ return makeDescriptionWithDecoration ( {
342
371
type : InternalSerializerType . BOOL as const ,
343
- } ;
372
+ } ) ;
344
373
} ,
345
- object < T extends { [ key : string ] : TypeDescription } > ( tag : string , props ?: T ) {
346
- return {
374
+ object < T extends { [ key : string ] : TypeDescription } > ( tag : string , props ?: T , withConstructor = false ) {
375
+ return makeDescriptionWithDecoration ( {
347
376
type : InternalSerializerType . OBJECT as const ,
348
377
options : {
349
378
tag,
350
379
props,
380
+ withConstructor,
351
381
} ,
352
- } ;
382
+ } ) ;
353
383
} ,
354
384
int8 ( ) {
355
- return {
385
+ return makeDescriptionWithDecoration ( {
356
386
type : InternalSerializerType . INT8 as const ,
357
- } ;
387
+ } ) ;
358
388
} ,
359
389
int16 ( ) {
360
- return {
390
+ return makeDescriptionWithDecoration ( {
361
391
type : InternalSerializerType . INT16 as const ,
362
- } ;
392
+ } ) ;
363
393
} ,
364
394
int32 ( ) {
365
- return {
395
+ return makeDescriptionWithDecoration ( {
366
396
type : InternalSerializerType . INT32 as const ,
367
- } ;
397
+ } ) ;
368
398
} ,
369
399
varInt32 ( ) {
370
- return {
400
+ return makeDescriptionWithDecoration ( {
371
401
type : InternalSerializerType . VAR_INT32 as const ,
372
- } ;
402
+ } ) ;
373
403
} ,
374
404
int64 ( ) {
375
- return {
405
+ return makeDescriptionWithDecoration ( {
376
406
type : InternalSerializerType . INT64 as const ,
377
- } ;
407
+ } ) ;
378
408
} ,
379
409
sliInt64 ( ) {
380
- return {
410
+ return makeDescriptionWithDecoration ( {
381
411
type : InternalSerializerType . SLI_INT64 as const ,
382
- } ;
412
+ } ) ;
383
413
} ,
384
414
float16 ( ) {
385
- return {
415
+ return makeDescriptionWithDecoration ( {
386
416
type : InternalSerializerType . FLOAT16 as const ,
387
- } ;
417
+ } ) ;
388
418
} ,
389
419
float32 ( ) {
390
- return {
420
+ return makeDescriptionWithDecoration ( {
391
421
type : InternalSerializerType . FLOAT32 as const ,
392
- } ;
422
+ } ) ;
393
423
} ,
394
424
float64 ( ) {
395
- return {
425
+ return makeDescriptionWithDecoration ( {
396
426
type : InternalSerializerType . FLOAT64 as const ,
397
- } ;
427
+ } ) ;
398
428
} ,
399
429
binary ( ) {
400
- return {
430
+ return makeDescriptionWithDecoration ( {
401
431
type : InternalSerializerType . BINARY as const ,
402
- } ;
432
+ } ) ;
403
433
} ,
404
434
duration ( ) {
405
- return {
435
+ return makeDescriptionWithDecoration ( {
406
436
type : InternalSerializerType . DURATION as const ,
407
- } ;
437
+ } ) ;
408
438
} ,
409
439
timestamp ( ) {
410
- return {
440
+ return makeDescriptionWithDecoration ( {
411
441
type : InternalSerializerType . TIMESTAMP as const ,
412
- } ;
442
+ } ) ;
413
443
} ,
414
444
boolArray ( ) {
415
- return {
445
+ return makeDescriptionWithDecoration ( {
416
446
type : InternalSerializerType . BOOL_ARRAY as const ,
417
- } ;
447
+ } ) ;
418
448
} ,
419
449
int8Array ( ) {
420
- return {
450
+ return makeDescriptionWithDecoration ( {
421
451
type : InternalSerializerType . INT8_ARRAY as const ,
422
- } ;
452
+ } ) ;
423
453
} ,
424
454
int16Array ( ) {
425
- return {
455
+ return makeDescriptionWithDecoration ( {
426
456
type : InternalSerializerType . INT16_ARRAY as const ,
427
- } ;
457
+ } ) ;
428
458
} ,
429
459
int32Array ( ) {
430
- return {
460
+ return makeDescriptionWithDecoration ( {
431
461
type : InternalSerializerType . INT32_ARRAY as const ,
432
- } ;
462
+ } ) ;
433
463
} ,
434
464
int64Array ( ) {
435
- return {
465
+ return makeDescriptionWithDecoration ( {
436
466
type : InternalSerializerType . INT64_ARRAY as const ,
437
- } ;
467
+ } ) ;
438
468
} ,
439
469
float16Array ( ) {
440
- return {
470
+ return makeDescriptionWithDecoration ( {
441
471
type : InternalSerializerType . FLOAT16_ARRAY as const ,
442
- } ;
472
+ } ) ;
443
473
} ,
444
474
float32Array ( ) {
445
- return {
475
+ return makeDescriptionWithDecoration ( {
446
476
type : InternalSerializerType . FLOAT32_ARRAY as const ,
447
- } ;
477
+ } ) ;
448
478
} ,
449
479
float64Array ( ) {
450
- return {
480
+ return makeDescriptionWithDecoration ( {
451
481
type : InternalSerializerType . FLOAT64_ARRAY as const ,
452
- } ;
482
+ } ) ;
453
483
} ,
454
484
} ;
485
+
486
+ const initMeta = ( target : new ( ) => any , description : ObjectTypeDescription ) => {
487
+ if ( ! target . prototype ) {
488
+ target . prototype = { } ;
489
+ }
490
+ target . prototype [ FuryClsInfoSymbol ] = {
491
+ toObjectDescription ( ) {
492
+ if ( targetFields . has ( target ) ) {
493
+ return Type . object ( description . options . tag , targetFields . get ( target ) , true ) ;
494
+ }
495
+ return Type . object ( description . options . tag , { } , true ) ;
496
+ } ,
497
+ constructor : target ,
498
+ } as ObjectFuryClsInfo ;
499
+ } ;
500
+
501
+ const targetFields = new WeakMap < new ( ) => any , { [ key : string ] : TypeDescription } > ( ) ;
502
+
503
+ const addField = ( target : new ( ) => any , key : string , des : TypeDescription ) => {
504
+ if ( ! targetFields . has ( target ) ) {
505
+ targetFields . set ( target , { } ) ;
506
+ }
507
+ targetFields . get ( target ) ! [ key ] = des ;
508
+ } ;
0 commit comments