@@ -13,62 +13,98 @@ import {
1313} from './module.graphql.mappers' ;
1414import stringify from 'fast-json-stable-stringify' ;
1515import { ConstDirectiveNode , DEFAULT_DEPRECATION_REASON , DocumentNode , Kind , print } from 'graphql' ;
16+ import { traceInlineSync } from '@hive/service-common' ;
1617import type { DateRange } from '../../shared/entities' ;
1718import type { PromiseOrValue } from '../../shared/helpers' ;
1819import { OperationsManager } from '../operations/providers/operations-manager' ;
1920import { TargetSelector } from '../shared/providers/storage' ;
2021import { SuperGraphInformation } from './lib/federation-super-graph' ;
2122
22- export function withUsedByClients <
23- T extends {
24- isUsed : boolean ;
25- } ,
26- > (
27- input : Record < string , T > ,
28- deps : {
29- operationsManager : OperationsManager ;
30- selector : TargetSelector ;
31- period : DateRange ;
32- typename : string ;
33- } ,
34- ) : Record <
35- string ,
36- T & {
37- usedByClients : ( ) => PromiseOrValue < Array < string > > ;
38- period : DateRange ;
39- organizationId : string ;
40- projectId : string ;
41- targetId : string ;
42- typename : string ;
43- }
44- > {
45- return Object . fromEntries (
46- Object . entries ( input ) . map ( ( [ schemaCoordinate , record ] ) => [
47- schemaCoordinate ,
48- {
49- selector : deps . selector ,
50- period : deps . period ,
51- typename : deps . typename ,
52- organizationId : deps . selector . organizationId ,
53- projectId : deps . selector . projectId ,
54- targetId : deps . selector . targetId ,
55- ...record ,
56- usedByClients ( ) {
57- if ( record . isUsed === false ) {
58- return [ ] ;
59- }
23+ export const withUsedByClients = traceInlineSync (
24+ 'withUsedByClients' ,
25+ { } ,
26+ function withUsedByClients <
27+ T extends {
28+ isUsed : boolean ;
29+ } ,
30+ > (
31+ input : Record < string , T > ,
32+ deps : {
33+ operationsManager : OperationsManager ;
34+ selector : TargetSelector ;
35+ period : DateRange ;
36+ typename : string ;
37+ } ,
38+ ) : Record <
39+ string ,
40+ T & {
41+ usedByClients : ( ) => PromiseOrValue < Array < string > > ;
42+ period : DateRange ;
43+ organizationId : string ;
44+ projectId : string ;
45+ targetId : string ;
46+ typename : string ;
47+ }
48+ > {
49+ // input can contain ALLLLLLLLLL the schema coordinates.
50+ // in order to be more efficient we lazily create the properties here as we could accidentially create way tooo much stuff!
51+ return new Proxy ( input , {
52+ get ( target , property , receiver ) {
53+ if (
54+ typeof property !== 'string' ||
55+ /** some code might check if this is a promise :D */
56+ property === 'then'
57+ ) {
58+ return Reflect . get ( target , property , receiver ) ;
59+ }
6060
61- // It's using DataLoader under the hood so it's safe to call it multiple times for different coordinates
62- return deps . operationsManager . getClientNamesPerCoordinateOfType ( {
63- ...deps . selector ,
64- period : deps . period ,
65- schemaCoordinate,
66- } ) ;
67- } ,
61+ // Guard against trying to look up properties that do not belong to this typename!
62+ if ( ! property . startsWith ( deps . typename ) ) {
63+ return undefined ;
64+ }
65+
66+ const schemaCoordinate = property ;
67+ const record = input [ property ] ;
68+
69+ if ( ! record ) {
70+ return undefined ;
71+ }
72+
73+ return {
74+ selector : deps . selector ,
75+ period : deps . period ,
76+ typename : deps . typename ,
77+ organizationId : deps . selector . organizationId ,
78+ projectId : deps . selector . projectId ,
79+ targetId : deps . selector . targetId ,
80+ ...record ,
81+ usedByClients ( ) {
82+ if ( record . isUsed === false ) {
83+ return [ ] ;
84+ }
85+
86+ // It's using DataLoader under the hood so it's safe to call it multiple times for different coordinates
87+ return deps . operationsManager . getClientNamesPerCoordinateOfType ( {
88+ ...deps . selector ,
89+ period : deps . period ,
90+ schemaCoordinate,
91+ } ) ;
92+ } ,
93+ } ;
6894 } ,
69- ] ) ,
70- ) ;
71- }
95+ } ) as Record <
96+ string ,
97+ T & {
98+ usedByClients : ( ) => PromiseOrValue < Array < string > > ;
99+ period : DateRange ;
100+ organizationId : string ;
101+ projectId : string ;
102+ targetId : string ;
103+ typename : string ;
104+ }
105+ > ;
106+ } ,
107+ ) ;
72108
73109function deprecationReasonFromDirectives ( directives : readonly ConstDirectiveNode [ ] | undefined ) {
74110 if ( ! directives ) {
0 commit comments