22 * Generates the default fragment for a collection
33 * = a fragment containing all fields
44 */
5- import { getFragmentFieldNames } from '../schema_utils' ;
5+ import { getFragmentFieldNames , createSchema } from '../schema_utils' ;
66import { isBlackbox } from '../simpleSchema_utils' ;
7+ import { registerFragment } from '../fragments.js' ;
8+
79
810const intlSuffix = '_intl' ;
911
1012// get fragment for a whole object (root schema or nested schema of an object or an array)
11- const getObjectFragment = ( {
12- schema,
13- fragmentName,
14- options
13+ export const getObjectFragment = ( {
14+ schema,
15+ fragmentName,
16+ options,
1517} ) => {
16- const fieldNames = getFragmentFieldNames ( { schema, options } ) ;
17- const childFragments = fieldNames . length && fieldNames . map ( fieldName => getFieldFragment ( {
18- schema,
19- fieldName,
20- options,
21- getObjectFragment : getObjectFragment
22- } ) )
23- // remove empty values
24- . filter ( f => ! ! f ) ;
25- if ( childFragments . length ) {
26- return `${ fragmentName } { ${ childFragments . join ( '\n' ) } }` ;
27- }
28- return null ;
18+ const fieldNames = getFragmentFieldNames ( { schema, options } ) ;
19+ const childFragments = fieldNames . length && fieldNames . map ( fieldName => getFieldFragment ( {
20+ schema,
21+ fieldName,
22+ options,
23+ getObjectFragment : getObjectFragment ,
24+ } ) )
25+ // remove empty values
26+ . filter ( f => ! ! f ) ;
27+ if ( childFragments . length ) {
28+ return `${ fragmentName } { ${ childFragments . join ( '\n' ) } }` ;
29+ }
30+ return null ;
2931} ;
3032
3133// get fragment for a specific field (either the field name or a nested fragment)
3234export const getFieldFragment = ( {
33- schema,
34- fieldName,
35- options,
36- getObjectFragment = getObjectFragment // a callback to call on nested schema
35+ schema,
36+ fieldName,
37+ options,
38+ getObjectFragment = getObjectFragment , // a callback to call on nested schema
3739} ) => {
38- // intl
39- if ( fieldName . slice ( - 5 ) === intlSuffix ) {
40- return `${ fieldName } { locale value }` ;
41- }
42- if ( fieldName === '_id' ) return fieldName ;
43- const field = schema [ fieldName ] ;
44-
45- const fieldType = field . type . singleType ;
46- const fieldTypeName =
47- typeof fieldType === 'object' ? 'Object' : typeof fieldType === 'function' ? fieldType . name : fieldType ;
48-
49- switch ( fieldTypeName ) {
50- case 'Object' :
51- if ( ! isBlackbox ( field ) && fieldType . _schema ) {
52- return getObjectFragment ( {
53- fragmentName : fieldName ,
54- schema : fieldType . _schema ,
55- options
56- } ) || null ;
57- }
58- return fieldName ;
59- case 'Array' :
60- const arrayItemFieldName = `${ fieldName } .$` ;
61- const arrayItemField = schema [ arrayItemFieldName ] ;
62- // note: make sure field has an associated array item field
63- if ( arrayItemField ) {
64- // child will either be native value or a an object (first case)
65- const arrayItemFieldType = arrayItemField . type . singleType ;
66- if ( ! isBlackbox ( field ) && arrayItemFieldType . _schema ) {
67- return getObjectFragment ( {
68- fragmentName : fieldName ,
69- schema : arrayItemFieldType . _schema ,
70- options
71- } ) || null ;
72- }
73- }
74- return fieldName ;
75- default :
76- return fieldName ; // fragment = fieldName
77- }
40+ // intl
41+ if ( fieldName . slice ( - 5 ) === intlSuffix ) {
42+ return `${ fieldName } { locale value }` ;
43+ }
44+ if ( fieldName === '_id' ) return fieldName ;
45+ const field = schema [ fieldName ] ;
46+
47+ const fieldType = field . type . singleType ;
48+ const fieldTypeName =
49+ typeof fieldType === 'object' ? 'Object' : typeof fieldType === 'function' ? fieldType . name : fieldType ;
50+
51+ switch ( fieldTypeName ) {
52+ case 'Object' :
53+ if ( ! isBlackbox ( field ) && fieldType . _schema ) {
54+ return getObjectFragment ( {
55+ fragmentName : fieldName ,
56+ schema : fieldType . _schema ,
57+ options,
58+ } ) || null ;
59+ }
60+ return fieldName ;
61+ case 'Array' :
62+ const arrayItemFieldName = `${ fieldName } .$` ;
63+ const arrayItemField = schema [ arrayItemFieldName ] ;
64+ // note: make sure field has an associated array item field
65+ if ( arrayItemField ) {
66+ // child will either be native value or a an object (first case)
67+ const arrayItemFieldType = arrayItemField . type . singleType ;
68+ if ( ! isBlackbox ( field ) && arrayItemFieldType . _schema ) {
69+ return getObjectFragment ( {
70+ fragmentName : fieldName ,
71+ schema : arrayItemFieldType . _schema ,
72+ options,
73+ } ) || null ;
74+ }
75+ }
76+ return fieldName ;
77+ default :
78+ return fieldName ; // fragment = fieldName
79+ }
7880} ;
7981
82+
8083/*
8184
8285Create default "dumb" gql fragment object for a given collection
8386
8487*/
8588export const getDefaultFragmentText = ( collection , options = { onlyViewable : true } ) => {
86- const schema = collection . simpleSchema ( ) . _schema ;
87- return getObjectFragment ( {
88- schema,
89- fragmentName : `fragment ${ collection . options . collectionName } DefaultFragment on ${ collection . typeName } ` ,
90- options
91- } ) || null ;
89+ const schema = collection . simpleSchema ( ) . _schema ;
90+ return getObjectFragment ( {
91+ schema,
92+ fragmentName : `fragment ${ collection . options . collectionName } DefaultFragment on ${ collection . typeName } ` ,
93+ options,
94+ } ) || null ;
9295} ;
9396
94- export default getDefaultFragmentText ;
97+ export default getDefaultFragmentText ;
98+
99+
100+ /**
101+ * Generates and registers a default fragment for a typeName registered using `registerCustomQuery()`
102+ * @param {string } typeName The GraphQL Type registered using `registerCustomQuery()`
103+ * @param {Object|SimpleSchema } [schema] Schema definition object to convert to a fragment
104+ * @param {String } [fragmentName] The fragment's name; if omitted `${typeName}DefaultFragment` will be used
105+ * @param {[String] } [defaultCanRead] Fields in the schema without `canRead` will be assigned these read permissions
106+ * @param {Object } options Options sent to `getObjectFragment()`
107+ */
108+ export const registerCustomDefaultFragment = function ( {
109+ typeName,
110+ schema,
111+ fragmentName,
112+ defaultCanRead,
113+ options = { onlyViewable : true } ,
114+ } ) {
115+ const simpleSchema = createSchema ( schema , undefined , undefined , defaultCanRead ) ;
116+ schema = simpleSchema . _schema ;
117+
118+ fragmentName = fragmentName || `${ typeName } DefaultFragment` ;
119+
120+ const defaultFragment = getObjectFragment ( {
121+ schema,
122+ fragmentName : `fragment ${ fragmentName } on ${ typeName } ` ,
123+ options,
124+ } ) ;
125+
126+ if ( defaultFragment ) registerFragment ( defaultFragment ) ;
127+ } ;
0 commit comments