@@ -13,6 +13,12 @@ export type FindManyPublicParams<S extends Schema.Schema.AnyNoContext> = {
1313 space : string ;
1414 first ?: number | undefined ;
1515 offset ?: number | undefined ;
16+ orderBy ?:
17+ | {
18+ property : keyof Schema . Schema . Type < S > ;
19+ direction : 'asc' | 'desc' ;
20+ }
21+ | undefined ;
1622} ;
1723
1824const entitiesQueryDocumentLevel0 = gql `
@@ -172,6 +178,168 @@ query entities($spaceId: UUID!, $typeIds: [UUID!]!, $relationTypeIdsLevel1: [UUI
172178}
173179` ;
174180
181+ const entitiesOrderedByPropertyQueryDocumentLevel0 = gql `
182+ query entitiesOrderedByProperty($spaceId: UUID!, $typeIds: [UUID!]!, $first: Int, $filter: EntityFilter!, $offset: Int, $propertyId: UUID!, $sortDirection: SortOrder!) {
183+ entities: entitiesOrderedByProperty(
184+ filter: { and: [{
185+ relations: {some: {typeId: {is: "8f151ba4-de20-4e3c-9cb4-99ddf96f48f1"}, toEntityId: {in: $typeIds}}},
186+ spaceIds: {in: [$spaceId]},
187+ }, $filter]}
188+ first: $first
189+ offset: $offset
190+ propertyId: $propertyId
191+ sortDirection: $sortDirection
192+ ) {
193+ id
194+ name
195+ valuesList(filter: {spaceId: {is: $spaceId}}) {
196+ propertyId
197+ string
198+ boolean
199+ number
200+ time
201+ point
202+ }
203+ }
204+ }
205+ ` ;
206+
207+ const entitiesOrderedByPropertyQueryDocumentLevel1 = gql `
208+ query entitiesOrderedByProperty($spaceId: UUID!, $typeIds: [UUID!]!, $relationTypeIdsLevel1: [UUID!]!, $first: Int, $filter: EntityFilter!, $offset: Int, $propertyId: UUID!, $sortDirection: SortOrder!) {
209+ entities: entitiesOrderedByProperty(
210+ first: $first
211+ filter: { and: [{
212+ relations: {some: {typeId: {is: "8f151ba4-de20-4e3c-9cb4-99ddf96f48f1"}, toEntityId: {in: $typeIds}}},
213+ spaceIds: {in: [$spaceId]},
214+ }, $filter]}
215+ offset: $offset
216+ propertyId: $propertyId
217+ sortDirection: $sortDirection
218+ ) {
219+ id
220+ name
221+ valuesList(filter: {spaceId: {is: $spaceId}}) {
222+ propertyId
223+ string
224+ boolean
225+ number
226+ time
227+ point
228+ }
229+ relationsList(
230+ filter: {spaceId: {is: $spaceId}, typeId:{ in: $relationTypeIdsLevel1}},
231+ ) {
232+ id
233+ entity {
234+ valuesList(filter: {spaceId: {is: $spaceId}}) {
235+ propertyId
236+ string
237+ boolean
238+ number
239+ time
240+ point
241+ }
242+ }
243+ toEntity {
244+ id
245+ name
246+ valuesList(filter: {spaceId: {is: $spaceId}}) {
247+ propertyId
248+ string
249+ boolean
250+ number
251+ time
252+ point
253+ }
254+ }
255+ typeId
256+ }
257+ }
258+ }
259+ ` ;
260+
261+ const entitiesOrderedByPropertyQueryDocumentLevel2 = gql `
262+ query entitiesOrderedByProperty($spaceId: UUID!, $typeIds: [UUID!]!, $relationTypeIdsLevel1: [UUID!]!, $relationTypeIdsLevel2: [UUID!]!, $first: Int, $filter: EntityFilter!, $offset: Int, $propertyId: UUID!, $sortDirection: SortOrder!) {
263+ entities: entitiesOrderedByProperty(
264+ first: $first
265+ filter: { and: [{
266+ relations: {some: {typeId: {is: "8f151ba4-de20-4e3c-9cb4-99ddf96f48f1"}, toEntityId: {in: $typeIds}}},
267+ spaceIds: {in: [$spaceId]},
268+ }, $filter]}
269+ offset: $offset
270+ propertyId: $propertyId
271+ sortDirection: $sortDirection
272+ ) {
273+ id
274+ name
275+ valuesList(filter: {spaceId: {is: $spaceId}}) {
276+ propertyId
277+ string
278+ boolean
279+ number
280+ time
281+ point
282+ }
283+ relationsList(
284+ filter: {spaceId: {is: $spaceId}, typeId:{ in: $relationTypeIdsLevel1}},
285+ ) {
286+ id
287+ entity {
288+ valuesList(filter: {spaceId: {is: $spaceId}}) {
289+ propertyId
290+ string
291+ boolean
292+ number
293+ time
294+ point
295+ }
296+ }
297+ toEntity {
298+ id
299+ name
300+ valuesList(filter: {spaceId: {is: $spaceId}}) {
301+ propertyId
302+ string
303+ boolean
304+ number
305+ time
306+ point
307+ }
308+ relationsList(
309+ filter: {spaceId: {is: $spaceId}, typeId:{ in: $relationTypeIdsLevel2}},
310+ ) {
311+ id
312+ entity {
313+ valuesList(filter: {spaceId: {is: $spaceId}}) {
314+ propertyId
315+ string
316+ boolean
317+ number
318+ time
319+ point
320+ }
321+ }
322+ toEntity {
323+ id
324+ name
325+ valuesList(filter: {spaceId: {is: $spaceId}}) {
326+ propertyId
327+ string
328+ boolean
329+ number
330+ time
331+ point
332+ }
333+ }
334+ typeId
335+ }
336+ }
337+ typeId
338+ }
339+ }
340+ }
341+ ` ;
342+
175343type EntityQueryResult = {
176344 entities : {
177345 id : string ;
@@ -239,6 +407,8 @@ type EntityQueryResult = {
239407 } [ ] ;
240408} ;
241409
410+ type GraphSortDirection = 'ASC' | 'DESC' ;
411+
242412export const parseResult = < S extends Schema . Schema . AnyNoContext > ( queryData : EntityQueryResult , type : S ) => {
243413 const schemaWithId = Utils . addIdSchemaField ( type ) ;
244414 const decode = Schema . decodeUnknownEither ( schemaWithId ) ;
@@ -296,7 +466,7 @@ export const findManyPublic = async <S extends Schema.Schema.AnyNoContext>(
296466 type : S ,
297467 params ?: FindManyPublicParams < S > ,
298468) => {
299- const { filter, include, space, first = 100 , offset = 0 } = params ?? { } ;
469+ const { filter, include, space, first = 100 , offset = 0 , orderBy } = params ?? { } ;
300470
301471 // constructing the relation type ids for the query
302472 const relationTypeIds = Utils . getRelationTypeIds ( type , include ) ;
@@ -305,25 +475,66 @@ export const findManyPublic = async <S extends Schema.Schema.AnyNoContext>(
305475 Option . getOrElse ( ( ) => [ ] ) ,
306476 ) ;
307477
308- let queryDocument = entitiesQueryDocumentLevel0 ;
309- if ( relationTypeIds . level1 . length > 0 ) {
310- queryDocument = entitiesQueryDocumentLevel1 ;
311- }
312- if ( relationTypeIds . level2 . length > 0 ) {
313- queryDocument = entitiesQueryDocumentLevel2 ;
478+ const relationLevel = relationTypeIds . level2 . length > 0 ? 2 : relationTypeIds . level1 . length > 0 ? 1 : 0 ;
479+
480+ let orderByPropertyId : string | undefined ;
481+ let sortDirection : GraphSortDirection | undefined ;
482+
483+ if ( orderBy ) {
484+ const ast = type . ast as SchemaAST . TypeLiteral ;
485+ const propertySignature = ast . propertySignatures . find ( ( prop ) => String ( prop . name ) === String ( orderBy . property ) ) ;
486+
487+ if ( ! propertySignature ) {
488+ throw new Error ( `Cannot order by unknown property "${ String ( orderBy . property ) } "` ) ;
489+ }
490+
491+ const propertyType =
492+ propertySignature . isOptional && SchemaAST . isUnion ( propertySignature . type )
493+ ? ( propertySignature . type . types . find ( ( member ) => ! SchemaAST . isUndefinedKeyword ( member ) ) ??
494+ propertySignature . type )
495+ : propertySignature . type ;
496+
497+ const propertyIdAnnotation = SchemaAST . getAnnotation < string > ( Constants . PropertyIdSymbol ) ( propertyType ) ;
498+
499+ if ( Option . isNone ( propertyIdAnnotation ) ) {
500+ throw new Error ( `Property "${ String ( orderBy . property ) } " is missing a propertyId annotation` ) ;
501+ }
502+
503+ orderByPropertyId = propertyIdAnnotation . value ;
504+ sortDirection = orderBy . direction === 'asc' ? 'ASC' : 'DESC' ;
314505 }
315506
507+ const queryDocument =
508+ relationLevel === 2
509+ ? orderBy
510+ ? entitiesOrderedByPropertyQueryDocumentLevel2
511+ : entitiesQueryDocumentLevel2
512+ : relationLevel === 1
513+ ? orderBy
514+ ? entitiesOrderedByPropertyQueryDocumentLevel1
515+ : entitiesQueryDocumentLevel1
516+ : orderBy
517+ ? entitiesOrderedByPropertyQueryDocumentLevel0
518+ : entitiesQueryDocumentLevel0 ;
519+
316520 const filterParams = filter ? Utils . translateFilterToGraphql ( filter , type ) : { } ;
317521
318- const result = await request < EntityQueryResult > ( ` ${ Graph . TESTNET_API_ORIGIN } /graphql` , queryDocument , {
522+ const queryVariables : Record < string , unknown > = {
319523 spaceId : space ,
320524 typeIds,
321525 relationTypeIdsLevel1 : relationTypeIds . level1 ,
322526 relationTypeIdsLevel2 : relationTypeIds . level2 ,
323527 first,
324528 filter : filterParams ,
325529 offset,
326- } ) ;
530+ } ;
531+
532+ if ( orderByPropertyId && sortDirection ) {
533+ queryVariables . propertyId = orderByPropertyId ;
534+ queryVariables . sortDirection = sortDirection ;
535+ }
536+
537+ const result = await request < EntityQueryResult > ( `${ Graph . TESTNET_API_ORIGIN } /graphql` , queryDocument , queryVariables ) ;
327538
328539 const { data, invalidEntities } = parseResult ( result , type ) ;
329540 return { data, invalidEntities } ;
0 commit comments