1
- import { parse } from 'graphql' ;
1
+ import { Kind , parse , type DocumentNode } from 'graphql' ;
2
2
import { print } from 'graphql/language/printer' ;
3
- import type { DocumentNode } from 'graphql' ;
4
3
import type { SiteLocale } from '@lib/i18n/types' ;
5
4
import { titleSuffix } from '@lib/seo' ;
6
5
import { datocmsBuildTriggerId , datocmsEnvironment } from '../../../datocms-environment' ;
@@ -61,8 +60,13 @@ interface CollectionData<CollectionType> {
61
60
[ key : string ] : CollectionType [ ] ;
62
61
}
63
62
64
- type CollectionMeta = {
65
- count : number ;
63
+ type CollectionInfo = {
64
+ meta : {
65
+ count : number ;
66
+ }
67
+ records : [ {
68
+ __typename : string ;
69
+ } ]
66
70
} ;
67
71
68
72
/**
@@ -72,35 +76,50 @@ type CollectionMeta = {
72
76
* DatoCMS GraphQL API has a limit of 100 records per request.
73
77
* This function uses pagination to get all records.
74
78
* @see https://www.datocms.com/docs/content-delivery-api/pagination
79
+ *
80
+ * @param {string } params.collection
81
+ * - The name of the DatoCMS collection. For example, `"Pages"`
82
+ * @param {DocumentNode|string } params.fragment
83
+ * - The GraphQL fragment to include for each record, For example `pageRouteFragment`.
75
84
*/
76
85
export const datocmsCollection = async < CollectionType > ( {
77
86
collection,
78
87
fragment
79
88
} : {
80
- collection : string ,
81
- fragment : string
89
+ collection : string ;
90
+ fragment : string | DocumentNode ;
82
91
} ) => {
83
- const { meta } = await datocmsRequest ( {
92
+ const {
93
+ meta,
94
+ records : [ { __typename : type } ]
95
+ } = await datocmsRequest < CollectionInfo > ( {
84
96
query : parse ( /* graphql */ `
85
97
query ${ collection } Meta {
98
+ records: all${ collection } (first: 1) { __typename }
86
99
meta: _all${ collection } Meta { count }
87
100
}
88
101
` )
89
- } ) as { meta : CollectionMeta } ;
90
-
102
+ } ) ;
91
103
const recordsPerPage = 100 ; // DatoCMS GraphQL API has a limit of 100 records per request
92
104
const totalPages = Math . ceil ( meta . count / recordsPerPage ) ;
93
105
const records : CollectionType [ ] = [ ] ;
94
-
106
+ const fragmentDocument = typeof fragment === 'string'
107
+ ? parse ( `fragment InlineFragment on ${ type } { ${ fragment } }` )
108
+ : fragment ;
109
+ const { definitions } = fragmentDocument ;
110
+ const fragmentDefinition = definitions . find ( ( { kind } ) => kind === Kind . FRAGMENT_DEFINITION ) ;
111
+
95
112
for ( let page = 0 ; page < totalPages ; page ++ ) {
96
113
const data = await datocmsRequest ( {
97
114
query : parse ( /* graphql */ `
115
+ ${ print ( fragmentDocument ) }
116
+
98
117
query All${ collection } {
99
118
${ collection } : all${ collection } (
100
119
first: ${ recordsPerPage } ,
101
120
skip: ${ page * recordsPerPage }
102
121
) {
103
- ${ fragment }
122
+ ... ${ fragmentDefinition ?. name ?. value }
104
123
}
105
124
}
106
125
` ) ,
0 commit comments