@@ -4635,4 +4635,194 @@ describe('paginate', () => {
46354635 } )
46364636 } )
46374637 } )
4638+
4639+ describe ( 'Wildcard Select' , ( ) => {
4640+ it ( 'should expand * wildcard to all main entity columns' , async ( ) => {
4641+ const query : PaginateQuery = {
4642+ page : 1 ,
4643+ limit : 10 ,
4644+ select : [ '*' ] ,
4645+ path : '/cats' ,
4646+ }
4647+
4648+ const result = await paginate ( query , catRepo , {
4649+ sortableColumns : [ 'id' ] ,
4650+ select : [ '*' ] ,
4651+ } )
4652+
4653+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'id' )
4654+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'name' )
4655+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'color' )
4656+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'age' )
4657+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'cutenessLevel' )
4658+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'lastVetVisit' )
4659+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'createdAt' )
4660+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'deletedAt' )
4661+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'weightChange' )
4662+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'size' )
4663+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'size.height' )
4664+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'size.width' )
4665+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'size.length' )
4666+ } )
4667+
4668+ it ( 'should expand relation.* wildcard to all relation columns' , async ( ) => {
4669+ const query : PaginateQuery = {
4670+ page : 1 ,
4671+ limit : 10 ,
4672+ select : [ 'id' , 'name' , 'toys.*' ] ,
4673+ path : '/cats' ,
4674+ }
4675+
4676+ const result = await paginate ( query , catRepo , {
4677+ sortableColumns : [ 'id' ] ,
4678+ select : [ 'id' , 'name' , 'toys.*' ] ,
4679+ relations : [ 'toys' ] ,
4680+ } )
4681+
4682+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'id' )
4683+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'name' )
4684+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'color' )
4685+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'age' )
4686+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'cutenessLevel' )
4687+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'lastVetVisit' )
4688+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'createdAt' )
4689+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'deletedAt' )
4690+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'weightChange' )
4691+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'id' )
4692+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'name' )
4693+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'createdAt' )
4694+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'size' )
4695+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'size.height' )
4696+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'size.width' )
4697+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'size.length' )
4698+ } )
4699+
4700+ it ( 'should handle both * and relation.* wildcards together' , async ( ) => {
4701+ const query : PaginateQuery = {
4702+ page : 1 ,
4703+ limit : 10 ,
4704+ select : [ '*' , 'toys.*' ] ,
4705+ path : '/cats' ,
4706+ }
4707+
4708+ const result = await paginate ( query , catRepo , {
4709+ sortableColumns : [ 'id' ] ,
4710+ select : [ '*' , 'toys.*' ] ,
4711+ relations : [ 'toys' ] ,
4712+ } )
4713+
4714+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'id' )
4715+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'name' )
4716+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'color' )
4717+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'age' )
4718+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'cutenessLevel' )
4719+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'lastVetVisit' )
4720+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'createdAt' )
4721+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'deletedAt' )
4722+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'weightChange' )
4723+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'id' )
4724+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'name' )
4725+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'createdAt' )
4726+ } )
4727+
4728+ it ( 'should handle non-existent relation wildcard gracefully' , async ( ) => {
4729+ const query : PaginateQuery = {
4730+ page : 1 ,
4731+ limit : 10 ,
4732+ select : [ 'id' , 'name' , 'nonExistentRelation.*' ] ,
4733+ path : '/cats' ,
4734+ }
4735+
4736+ const result = await paginate ( query , catRepo , {
4737+ sortableColumns : [ 'id' ] ,
4738+ select : [ 'id' , 'name' , 'nonExistentRelation.*' ] ,
4739+ } )
4740+
4741+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'id' )
4742+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'name' )
4743+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'nonExistentRelation.*' )
4744+ } )
4745+
4746+ it ( 'should handle nested relation wildcards correctly' , async ( ) => {
4747+ const query : PaginateQuery = {
4748+ page : 1 ,
4749+ limit : 10 ,
4750+ select : [ '*' , 'toys.*' , 'toys.shop.*' , 'toys.shop.address.*' ] ,
4751+ sortBy : [
4752+ [ 'id' , 'ASC' ] ,
4753+ [ 'toys.id' , 'ASC' ] ,
4754+ ] ,
4755+ path : '/cats' ,
4756+ }
4757+
4758+ const result = await paginate ( query , catRepo , {
4759+ sortableColumns : [ 'id' , 'toys.id' ] ,
4760+ select : [ '*' , 'toys.*' , 'toys.shop.*' , 'toys.shop.address.*' ] ,
4761+ relations : [ 'toys' , 'toys.shop' , 'toys.shop.address' ] ,
4762+ } )
4763+
4764+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'id' )
4765+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'name' )
4766+ expect ( result . data [ 0 ] . toys [ 1 ] ) . toHaveProperty ( 'id' )
4767+ expect ( result . data [ 0 ] . toys [ 1 ] ) . toHaveProperty ( 'name' )
4768+ expect ( result . data [ 0 ] . toys [ 1 ] . shop ) . toHaveProperty ( 'id' )
4769+ expect ( result . data [ 0 ] . toys [ 1 ] . shop ) . toHaveProperty ( 'shopName' )
4770+ expect ( result . data [ 0 ] . toys [ 1 ] . shop . address ) . toHaveProperty ( 'id' )
4771+ expect ( result . data [ 0 ] . toys [ 1 ] . shop . address ) . toHaveProperty ( 'address' )
4772+ } )
4773+
4774+ it ( 'should restrict query.select to only fields allowed in config.select' , async ( ) => {
4775+ // Server-side config only allows id and name
4776+ const config : PaginateConfig < CatEntity > = {
4777+ sortableColumns : [ 'id' ] ,
4778+ select : [ 'id' , 'name' ] ,
4779+ }
4780+
4781+ // Client tries to request additional fields
4782+ const query : PaginateQuery = {
4783+ page : 1 ,
4784+ limit : 10 ,
4785+ select : [ 'id' , 'name' , 'color' , 'age' ] , // color and age not in config.select
4786+ path : '/cats' ,
4787+ }
4788+
4789+ const result = await paginate ( query , catRepo , config )
4790+
4791+ // Should only include fields that exist in both config.select and query.select
4792+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'id' )
4793+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'name' )
4794+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'color' )
4795+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'age' )
4796+ } )
4797+
4798+ it ( 'should restrict wildcard query.select to only fields allowed in config.select' , async ( ) => {
4799+ // Server-side config only allows id, name and toys.id
4800+ const config : PaginateConfig < CatEntity > = {
4801+ sortableColumns : [ 'id' ] ,
4802+ select : [ 'id' , 'name' , 'toys.id' ] ,
4803+ relations : [ 'toys' ] ,
4804+ }
4805+
4806+ // Client tries to request all fields with wildcards
4807+ const query : PaginateQuery = {
4808+ page : 1 ,
4809+ limit : 10 ,
4810+ select : [ '*' , 'toys.*' ] , // Requesting all fields with wildcards
4811+ path : '/cats' ,
4812+ }
4813+
4814+ const result = await paginate ( query , catRepo , config )
4815+
4816+ // Should only include fields that exist in both expanded config.select and expanded query.select
4817+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'id' )
4818+ expect ( result . data [ 0 ] ) . toHaveProperty ( 'name' )
4819+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'color' )
4820+ expect ( result . data [ 0 ] ) . not . toHaveProperty ( 'age' )
4821+
4822+ // Should only have toys.id, not other toy properties
4823+ expect ( result . data [ 0 ] . toys [ 0 ] ) . toHaveProperty ( 'id' )
4824+ expect ( result . data [ 0 ] . toys [ 0 ] ) . not . toHaveProperty ( 'name' )
4825+ expect ( result . data [ 0 ] . toys [ 0 ] ) . not . toHaveProperty ( 'createdAt' )
4826+ } )
4827+ } )
46384828} )
0 commit comments