@strapi/plugin-graphql 4.0.0-next.2 → 4.0.0-next.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/admin/src/translations/zh-Hans.json +4 -0
  2. package/package.json +17 -15
  3. package/server/bootstrap.js +124 -0
  4. package/server/services/builders/dynamic-zones.js +96 -0
  5. package/server/services/builders/entity-meta.js +7 -0
  6. package/server/services/builders/entity.js +43 -0
  7. package/server/services/builders/enums.js +24 -0
  8. package/server/services/builders/filters/content-type.js +84 -0
  9. package/server/services/builders/filters/index.js +7 -0
  10. package/server/services/builders/filters/operators/and.js +15 -0
  11. package/server/services/builders/filters/operators/between.js +15 -0
  12. package/server/services/builders/filters/operators/contains.js +13 -0
  13. package/server/services/builders/filters/operators/containsi.js +13 -0
  14. package/server/services/builders/filters/operators/ends-with.js +13 -0
  15. package/server/services/builders/filters/operators/eq.js +19 -0
  16. package/server/services/builders/filters/operators/gt.js +13 -0
  17. package/server/services/builders/filters/operators/gte.js +13 -0
  18. package/server/services/builders/filters/operators/in.js +15 -0
  19. package/server/services/builders/filters/operators/index.js +38 -0
  20. package/server/services/builders/filters/operators/lt.js +13 -0
  21. package/server/services/builders/filters/operators/lte.js +13 -0
  22. package/server/services/builders/filters/operators/ne.js +13 -0
  23. package/server/services/builders/filters/operators/not-contains.js +13 -0
  24. package/server/services/builders/filters/operators/not-containsi.js +13 -0
  25. package/server/services/builders/filters/operators/not-in.js +15 -0
  26. package/server/services/builders/filters/operators/not-null.js +13 -0
  27. package/server/services/builders/filters/operators/not.js +19 -0
  28. package/server/services/builders/filters/operators/null.js +13 -0
  29. package/server/services/builders/filters/operators/or.js +15 -0
  30. package/server/services/builders/filters/operators/starts-with.js +13 -0
  31. package/server/services/builders/generic-morph.js +41 -0
  32. package/server/services/builders/index.js +92 -0
  33. package/server/services/builders/input.js +118 -0
  34. package/server/services/builders/mutations/collection-type.js +170 -0
  35. package/server/services/builders/mutations/index.js +9 -0
  36. package/server/services/builders/mutations/single-type.js +135 -0
  37. package/server/services/builders/queries/collection-type.js +120 -0
  38. package/server/services/builders/queries/index.js +9 -0
  39. package/server/services/builders/queries/single-type.js +70 -0
  40. package/server/services/builders/relation-response-collection.js +35 -0
  41. package/server/services/builders/resolvers/association.js +64 -0
  42. package/server/services/builders/resolvers/component.js +14 -0
  43. package/server/services/builders/resolvers/dynamic-zone.js +9 -0
  44. package/server/services/builders/resolvers/index.js +18 -0
  45. package/server/services/builders/resolvers/mutation.js +33 -0
  46. package/server/services/builders/resolvers/query.js +19 -0
  47. package/server/services/builders/response-collection.js +43 -0
  48. package/server/services/builders/response.js +32 -0
  49. package/server/services/builders/type.js +370 -0
  50. package/server/services/builders/utils.js +131 -0
  51. package/server/services/constants.js +147 -0
  52. package/server/services/content-api/index.js +168 -0
  53. package/server/services/content-api/policy.js +59 -0
  54. package/server/services/content-api/register-functions/collection-type.js +72 -0
  55. package/server/services/content-api/register-functions/component.js +15 -0
  56. package/server/services/content-api/register-functions/content-type/dynamic-zones.js +36 -0
  57. package/server/services/content-api/register-functions/content-type/enums.js +33 -0
  58. package/server/services/content-api/register-functions/content-type/filters.js +15 -0
  59. package/server/services/content-api/register-functions/content-type/index.js +13 -0
  60. package/server/services/content-api/register-functions/content-type/inputs.js +21 -0
  61. package/server/services/content-api/register-functions/index.js +22 -0
  62. package/server/services/content-api/register-functions/internals.js +13 -0
  63. package/server/services/content-api/register-functions/polymorphic.js +69 -0
  64. package/server/services/content-api/register-functions/scalars.js +14 -0
  65. package/server/services/content-api/register-functions/single-type.js +72 -0
  66. package/server/services/content-api/wrap-resolvers.js +146 -0
  67. package/server/services/extension/extension.js +95 -0
  68. package/server/services/extension/index.js +5 -0
  69. package/server/services/extension/shadow-crud-manager.js +159 -0
  70. package/server/services/format/index.js +7 -0
  71. package/server/services/format/return-types.js +27 -0
  72. package/server/services/index.js +21 -0
  73. package/server/services/internals/args/index.js +11 -0
  74. package/server/services/internals/args/pagination.js +19 -0
  75. package/server/services/internals/args/publication-state.js +12 -0
  76. package/server/services/internals/args/sort.js +10 -0
  77. package/server/services/internals/helpers/get-enabled-scalars.js +15 -0
  78. package/server/services/internals/helpers/index.js +7 -0
  79. package/server/services/internals/index.js +13 -0
  80. package/server/services/internals/scalars/index.js +18 -0
  81. package/server/services/internals/scalars/time.js +35 -0
  82. package/server/services/internals/types/error.js +33 -0
  83. package/server/services/internals/types/filters.js +39 -0
  84. package/server/services/internals/types/index.js +29 -0
  85. package/server/services/internals/types/pagination.js +24 -0
  86. package/server/services/internals/types/publication-state.js +24 -0
  87. package/server/services/internals/types/response-collection-meta.js +38 -0
  88. package/server/services/type-registry.js +103 -0
  89. package/server/services/utils/attributes.js +84 -0
  90. package/server/services/utils/index.js +11 -0
  91. package/server/services/utils/mappers/entity-to-response-entity.js +12 -0
  92. package/server/services/utils/mappers/graphql-filters-to-strapi-query.js +107 -0
  93. package/server/services/utils/mappers/graphql-scalar-to-operators.js +17 -0
  94. package/server/services/utils/mappers/index.js +13 -0
  95. package/server/services/utils/mappers/strapi-scalar-to-graphql-scalar.js +24 -0
  96. package/server/services/utils/naming.js +282 -0
  97. package/strapi-admin.js +3 -0
  98. package/strapi-server.js +11 -0
  99. package/config/routes.json +0 -3
  100. package/config/schema.graphql +0 -1
  101. package/config/settings.json +0 -12
  102. package/controllers/GraphQL.js +0 -9
  103. package/hooks/graphql/defaults.json +0 -5
  104. package/hooks/graphql/index.js +0 -174
  105. package/hooks/graphql/load-config.js +0 -42
  106. package/services/build-aggregation.js +0 -565
  107. package/services/data-loaders.js +0 -55
  108. package/services/naming.js +0 -15
  109. package/services/resolvers-builder.js +0 -204
  110. package/services/schema-definitions.js +0 -131
  111. package/services/schema-generator.js +0 -178
  112. package/services/shadow-crud.js +0 -612
  113. package/services/type-builder.js +0 -311
  114. package/services/utils.js +0 -200
  115. package/types/dynamiczoneScalar.js +0 -40
  116. package/types/publication-state.js +0 -16
  117. package/types/time.js +0 -26
@@ -0,0 +1,370 @@
1
+ 'use strict';
2
+
3
+ const { isArray, isString, isUndefined, constant } = require('lodash/fp');
4
+ const { objectType } = require('nexus');
5
+
6
+ const { contentTypes } = require('@strapi/utils');
7
+
8
+ /**
9
+ * @typedef TypeBuildersOptions
10
+ *
11
+ * @property {ObjectDefinitionBlock} builder
12
+ * @property {string} attributeName
13
+ * @property {object} attribute
14
+ * @property {object} contentType
15
+ * @property {object} context
16
+ * @property {object} context.strapi
17
+ * @property {object} context.registry
18
+ */
19
+ module.exports = context => {
20
+ const { strapi } = context;
21
+
22
+ const getGraphQLService = strapi.plugin('graphql').service;
23
+
24
+ const extension = getGraphQLService('extension');
25
+
26
+ /**
27
+ * Add a scalar attribute to the type definition
28
+ *
29
+ * The attribute is added based on a simple association between a Strapi
30
+ * type and a GraphQL type (the map is defined in `strapiTypeToGraphQLScalar`)
31
+ *
32
+ * @param {TypeBuildersOptions} options
33
+ */
34
+ const addScalarAttribute = ({ builder, attributeName, attribute }) => {
35
+ const { mappers } = getGraphQLService('utils');
36
+
37
+ const gqlType = mappers.strapiScalarToGraphQLScalar(attribute.type);
38
+
39
+ builder.field(attributeName, { type: gqlType });
40
+ };
41
+
42
+ /**
43
+ * Add a component attribute to the type definition
44
+ *
45
+ * The attribute is added by fetching the component's type
46
+ * name and using it as the attribute's type
47
+ *
48
+ * @param {TypeBuildersOptions} options
49
+ */
50
+ const addComponentAttribute = ({ builder, attributeName, contentType, attribute }) => {
51
+ const { naming } = getGraphQLService('utils');
52
+ const { getContentTypeArgs } = getGraphQLService('builders').utils;
53
+ const { buildComponentResolver } = getGraphQLService('builders').get('content-api');
54
+
55
+ const type = naming.getComponentNameFromAttribute(attribute);
56
+
57
+ if (attribute.repeatable) {
58
+ builder = builder.list;
59
+ }
60
+
61
+ const targetComponent = strapi.getModel(attribute.component);
62
+
63
+ const resolve = buildComponentResolver({
64
+ contentTypeUID: contentType.uid,
65
+ attributeName,
66
+ strapi,
67
+ });
68
+
69
+ const args = getContentTypeArgs(targetComponent);
70
+
71
+ builder.field(attributeName, { type, resolve, args });
72
+ };
73
+
74
+ /**
75
+ * Add a dynamic zone attribute to the type definition
76
+ *
77
+ * The attribute is added by fetching the dynamic zone's
78
+ * type name and using it as the attribute's type
79
+ *
80
+ * @param {TypeBuildersOptions} options
81
+ */
82
+ const addDynamicZoneAttribute = ({ builder, attributeName, contentType }) => {
83
+ const { naming } = getGraphQLService('utils');
84
+ const { ERROR_CODES } = getGraphQLService('constants');
85
+ const { buildDynamicZoneResolver } = getGraphQLService('builders').get('content-api');
86
+
87
+ const { components } = contentType.attributes[attributeName];
88
+
89
+ const isEmpty = components.length === 0;
90
+ const type = naming.getDynamicZoneName(contentType, attributeName);
91
+
92
+ const resolve = isEmpty
93
+ ? // If the dynamic zone don't have any component, then return an error payload
94
+ constant({
95
+ code: ERROR_CODES.emptyDynamicZone,
96
+ message: `This dynamic zone don't have any component attached to it`,
97
+ })
98
+ : // Else, return a classic dynamic-zone resolver
99
+ buildDynamicZoneResolver({
100
+ contentTypeUID: contentType.uid,
101
+ attributeName,
102
+ });
103
+
104
+ builder.list.field(attributeName, { type, resolve });
105
+ };
106
+
107
+ /**
108
+ * Add an enum attribute to the type definition
109
+ *
110
+ * The attribute is added by fetching the enum's type
111
+ * name and using it as the attribute's type
112
+ *
113
+ * @param {TypeBuildersOptions} options
114
+ */
115
+ const addEnumAttribute = ({ builder, attributeName, contentType }) => {
116
+ const { naming } = getGraphQLService('utils');
117
+
118
+ const type = naming.getEnumName(contentType, attributeName);
119
+
120
+ builder.field(attributeName, { type });
121
+ };
122
+
123
+ /**
124
+ * Add a media attribute to the type definition
125
+ * @param {TypeBuildersOptions} options
126
+ */
127
+ const addMediaAttribute = options => {
128
+ const { naming } = getGraphQLService('utils');
129
+ const { getContentTypeArgs } = getGraphQLService('builders').utils;
130
+ const { buildAssociationResolver } = getGraphQLService('builders').get('content-api');
131
+ const extension = getGraphQLService('extension');
132
+
133
+ let { builder } = options;
134
+ const { attributeName, attribute, contentType } = options;
135
+ const fileUID = 'plugin::upload.file';
136
+
137
+ if (extension.shadowCRUD(fileUID).isDisabled()) {
138
+ return;
139
+ }
140
+
141
+ const fileContentType = strapi.contentTypes[fileUID];
142
+
143
+ const resolve = buildAssociationResolver({
144
+ contentTypeUID: contentType.uid,
145
+ attributeName,
146
+ strapi,
147
+ });
148
+
149
+ const args = attribute.multiple ? getContentTypeArgs(fileContentType) : undefined;
150
+ const type = attribute.multiple
151
+ ? naming.getRelationResponseCollectionName(fileContentType)
152
+ : naming.getEntityResponseName(fileContentType);
153
+
154
+ builder.field(attributeName, { type, resolve, args });
155
+ };
156
+
157
+ /**
158
+ * Add a polymorphic relational attribute to the type definition
159
+ * @param {TypeBuildersOptions} options
160
+ */
161
+ const addPolymorphicRelationalAttribute = options => {
162
+ const { GENERIC_MORPH_TYPENAME } = getGraphQLService('constants');
163
+ const { naming } = getGraphQLService('utils');
164
+ const { buildAssociationResolver } = getGraphQLService('builders').get('content-api');
165
+
166
+ let { builder } = options;
167
+ const { attributeName, attribute, contentType } = options;
168
+
169
+ const { target } = attribute;
170
+ const isToManyRelation = attribute.relation.endsWith('Many');
171
+
172
+ if (isToManyRelation) {
173
+ builder = builder.list;
174
+ }
175
+ // todo[v4]: How to handle polymorphic relation w/ entity response collection types?
176
+ // -> Currently return raw polymorphic entities
177
+
178
+ const resolve = buildAssociationResolver({
179
+ contentTypeUID: contentType.uid,
180
+ attributeName,
181
+ strapi,
182
+ });
183
+
184
+ // If there is no specific target specified, then use the GenericMorph type
185
+ if (isUndefined(target)) {
186
+ builder.field(attributeName, {
187
+ type: GENERIC_MORPH_TYPENAME,
188
+ resolve,
189
+ });
190
+ }
191
+
192
+ // If the target is an array of string, resolve the associated morph type and use it
193
+ else if (isArray(target) && target.every(isString)) {
194
+ const type = naming.getMorphRelationTypeName(contentType, attributeName);
195
+
196
+ builder.field(attributeName, { type, resolve });
197
+ }
198
+ };
199
+
200
+ /**
201
+ * Add a regular relational attribute to the type definition
202
+ * @param {TypeBuildersOptions} options
203
+ */
204
+ const addRegularRelationalAttribute = options => {
205
+ const { naming } = getGraphQLService('utils');
206
+ const { getContentTypeArgs } = getGraphQLService('builders').utils;
207
+ const { buildAssociationResolver } = getGraphQLService('builders').get('content-api');
208
+ const extension = getGraphQLService('extension');
209
+
210
+ let { builder } = options;
211
+ const { attributeName, attribute, contentType } = options;
212
+
213
+ if (extension.shadowCRUD(attribute.target).isDisabled()) {
214
+ return;
215
+ }
216
+
217
+ const isToManyRelation = attribute.relation.endsWith('Many');
218
+
219
+ const resolve = buildAssociationResolver({
220
+ contentTypeUID: contentType.uid,
221
+ attributeName,
222
+ strapi,
223
+ });
224
+
225
+ const targetContentType = strapi.getModel(attribute.target);
226
+
227
+ const type = isToManyRelation
228
+ ? naming.getRelationResponseCollectionName(targetContentType)
229
+ : naming.getEntityResponseName(targetContentType);
230
+
231
+ const args = isToManyRelation ? getContentTypeArgs(targetContentType) : undefined;
232
+
233
+ builder.field(attributeName, { type, resolve, args });
234
+ };
235
+
236
+ const isNotPrivate = contentType => attributeName => {
237
+ return !contentTypes.isPrivateAttribute(contentType, attributeName);
238
+ };
239
+
240
+ const isNotDisabled = contentType => attributeName => {
241
+ return extension
242
+ .shadowCRUD(contentType.uid)
243
+ .field(attributeName)
244
+ .hasOutputEnabled();
245
+ };
246
+
247
+ return {
248
+ /**
249
+ * Create a type definition for a given content type
250
+ * @param contentType - The content type used to created the definition
251
+ * @return {NexusObjectTypeDef}
252
+ */
253
+ buildTypeDefinition(contentType) {
254
+ const utils = getGraphQLService('utils');
255
+
256
+ const { getComponentName, getTypeName } = utils.naming;
257
+ const {
258
+ isStrapiScalar,
259
+ isComponent,
260
+ isDynamicZone,
261
+ isEnumeration,
262
+ isMedia,
263
+ isMorphRelation,
264
+ isRelation,
265
+ } = utils.attributes;
266
+
267
+ const { attributes, modelType, options = {} } = contentType;
268
+
269
+ const attributesKey = Object.keys(attributes);
270
+ const hasTimestamps = isArray(options.timestamps);
271
+
272
+ const name = (modelType === 'component' ? getComponentName : getTypeName).call(
273
+ null,
274
+ contentType
275
+ );
276
+
277
+ return objectType({
278
+ name,
279
+
280
+ definition(t) {
281
+ if (modelType === 'component' && isNotDisabled(contentType)('id')) {
282
+ t.nonNull.id('id');
283
+ }
284
+
285
+ // 1. Timestamps
286
+ // If the content type has timestamps enabled
287
+ // then we should add the corresponding attributes in the definition
288
+ if (hasTimestamps) {
289
+ const [createdAtKey, updatedAtKey] = contentType.options.timestamps;
290
+
291
+ t.nonNull.dateTime(createdAtKey);
292
+ t.nonNull.dateTime(updatedAtKey);
293
+ }
294
+
295
+ /** 2. Attributes
296
+ *
297
+ * Attributes can be of 7 different kind:
298
+ * - Scalar
299
+ * - Component
300
+ * - Dynamic Zone
301
+ * - Enum
302
+ * - Media
303
+ * - Polymorphic Relations
304
+ * - Regular Relations
305
+ *
306
+ * Here, we iterate over each non-private attribute
307
+ * and add it to the type definition based on its type
308
+ */
309
+ attributesKey
310
+ // Ignore private attributes
311
+ .filter(isNotPrivate(contentType))
312
+ // Ignore disabled fields (from extension service)
313
+ .filter(isNotDisabled(contentType))
314
+ // Add each attribute to the type definition
315
+ .forEach(attributeName => {
316
+ const attribute = attributes[attributeName];
317
+
318
+ // We create a copy of the builder (t) to apply custom
319
+ // rules only on the current attribute (eg: nonNull, list, ...)
320
+ let builder = t;
321
+
322
+ if (attribute.required) {
323
+ builder = builder.nonNull;
324
+ }
325
+
326
+ /**
327
+ * @type {TypeBuildersOptions}
328
+ */
329
+ const options = { builder, attributeName, attribute, contentType, context };
330
+
331
+ // Scalars
332
+ if (isStrapiScalar(attribute)) {
333
+ addScalarAttribute(options);
334
+ }
335
+
336
+ // Components
337
+ else if (isComponent(attribute)) {
338
+ addComponentAttribute(options);
339
+ }
340
+
341
+ // Dynamic Zones
342
+ else if (isDynamicZone(attribute)) {
343
+ addDynamicZoneAttribute(options);
344
+ }
345
+
346
+ // Enums
347
+ else if (isEnumeration(attribute)) {
348
+ addEnumAttribute(options);
349
+ }
350
+
351
+ // Media
352
+ else if (isMedia(attribute)) {
353
+ addMediaAttribute(options);
354
+ }
355
+
356
+ // Polymorphic Relations
357
+ else if (isMorphRelation(attribute)) {
358
+ addPolymorphicRelationalAttribute(options);
359
+ }
360
+
361
+ // Regular Relations
362
+ else if (isRelation(attribute) || isMedia(attribute)) {
363
+ addRegularRelationalAttribute(options);
364
+ }
365
+ });
366
+ },
367
+ });
368
+ },
369
+ };
370
+ };
@@ -0,0 +1,131 @@
1
+ 'use strict';
2
+
3
+ const { entries, mapValues, omit } = require('lodash/fp');
4
+ const {
5
+ pagination: { withDefaultPagination },
6
+ contentTypes: { hasDraftAndPublish },
7
+ } = require('@strapi/utils');
8
+
9
+ module.exports = ({ strapi }) => {
10
+ const { service: getService } = strapi.plugin('graphql');
11
+
12
+ return {
13
+ /**
14
+ * Get every args for a given content type
15
+ * @param {object} contentType
16
+ * @param {object} options
17
+ * @param {boolean} options.multiple
18
+ * @return {object}
19
+ */
20
+ getContentTypeArgs(contentType, { multiple = true } = {}) {
21
+ const { naming } = getService('utils');
22
+ const { args } = getService('internals');
23
+
24
+ const { kind, modelType } = contentType;
25
+
26
+ // Components
27
+ if (modelType === 'component') {
28
+ return {
29
+ filters: naming.getFiltersInputTypeName(contentType),
30
+ pagination: args.PaginationArg,
31
+ sort: args.SortArg,
32
+ };
33
+ }
34
+
35
+ // Collection Types
36
+ else if (kind === 'collectionType') {
37
+ if (!multiple) {
38
+ return { id: 'ID' };
39
+ }
40
+
41
+ const params = {
42
+ filters: naming.getFiltersInputTypeName(contentType),
43
+ pagination: args.PaginationArg,
44
+ sort: args.SortArg,
45
+ };
46
+
47
+ if (hasDraftAndPublish(contentType)) {
48
+ Object.assign(params, { publicationState: args.PublicationStateArg });
49
+ }
50
+
51
+ return params;
52
+ }
53
+
54
+ // Single Types
55
+ else if (kind === 'singleType') {
56
+ const params = {};
57
+
58
+ if (hasDraftAndPublish(contentType)) {
59
+ Object.assign(params, { publicationState: args.PublicationStateArg });
60
+ }
61
+
62
+ return params;
63
+ }
64
+ },
65
+
66
+ /**
67
+ * Filter an object entries and keep only those whose value is a unique scalar attribute
68
+ * @param {object} attributes
69
+ * @return {Object<string, object>}
70
+ */
71
+ getUniqueScalarAttributes(attributes) {
72
+ const { isStrapiScalar } = getService('utils').attributes;
73
+
74
+ const uniqueAttributes = entries(attributes).filter(
75
+ ([, attribute]) => isStrapiScalar(attribute) && attribute.unique
76
+ );
77
+
78
+ return Object.fromEntries(uniqueAttributes);
79
+ },
80
+
81
+ /**
82
+ * Map each value from an attribute to a FiltersInput type name
83
+ * @param {object} attributes - The attributes object to transform
84
+ * @return {Object<string, string>}
85
+ */
86
+ scalarAttributesToFiltersMap: mapValues(attribute => {
87
+ const { mappers, naming } = getService('utils');
88
+
89
+ const gqlScalar = mappers.strapiScalarToGraphQLScalar(attribute.type);
90
+
91
+ return naming.getScalarFilterInputTypeName(gqlScalar);
92
+ }),
93
+
94
+ /**
95
+ * Apply basic transform to GQL args
96
+ */
97
+ transformArgs(args, { contentType, usePagination = false } = {}) {
98
+ const { mappers } = getService('utils');
99
+ const { pagination = {}, filters = {} } = args;
100
+
101
+ // Init
102
+ const newArgs = omit(['pagination', 'filters'], args);
103
+
104
+ // Pagination
105
+ if (usePagination) {
106
+ const defaultLimit = strapi.plugin('graphql').config('defaultLimit');
107
+ const maxLimit = strapi.plugin('graphql').config('maxLimit', -1);
108
+
109
+ Object.assign(
110
+ newArgs,
111
+ withDefaultPagination(pagination, {
112
+ maxLimit,
113
+ defaults: {
114
+ offset: { limit: defaultLimit },
115
+ page: { pageSize: defaultLimit },
116
+ },
117
+ })
118
+ );
119
+ }
120
+
121
+ // Filters
122
+ if (args.filters) {
123
+ Object.assign(newArgs, {
124
+ filters: mappers.graphQLFiltersToStrapiQuery(filters, contentType),
125
+ });
126
+ }
127
+
128
+ return newArgs;
129
+ },
130
+ };
131
+ };
@@ -0,0 +1,147 @@
1
+ 'use strict';
2
+
3
+ const PAGINATION_TYPE_NAME = 'Pagination';
4
+ const PUBLICATION_STATE_TYPE_NAME = 'PublicationState';
5
+ const ERROR_TYPE_NAME = 'Error';
6
+
7
+ const RESPONSE_COLLECTION_META_TYPE_NAME = 'ResponseCollectionMeta';
8
+
9
+ const GRAPHQL_SCALARS = [
10
+ 'ID',
11
+ 'Boolean',
12
+ 'Int',
13
+ 'String',
14
+ 'Long',
15
+ 'Float',
16
+ 'JSON',
17
+ 'Date',
18
+ 'Time',
19
+ 'DateTime',
20
+ ];
21
+
22
+ const STRAPI_SCALARS = [
23
+ 'boolean',
24
+ 'integer',
25
+ 'string',
26
+ 'richtext',
27
+ 'biginteger',
28
+ 'float',
29
+ 'decimal',
30
+ 'json',
31
+ 'date',
32
+ 'time',
33
+ 'datetime',
34
+ 'timestamp',
35
+ 'uid',
36
+ 'email',
37
+ 'password',
38
+ 'text',
39
+ ];
40
+
41
+ const SCALARS_ASSOCIATIONS = {
42
+ uid: 'String',
43
+ email: 'String',
44
+ password: 'String',
45
+ text: 'String',
46
+ boolean: 'Boolean',
47
+ integer: 'Int',
48
+ string: 'String',
49
+ richtext: 'String',
50
+ biginteger: 'Long',
51
+ float: 'Float',
52
+ decimal: 'Float',
53
+ json: 'JSON',
54
+ date: 'Date',
55
+ time: 'Time',
56
+ datetime: 'DateTime',
57
+ timestamp: 'DateTime',
58
+ };
59
+
60
+ const GENERIC_MORPH_TYPENAME = 'GenericMorph';
61
+
62
+ const KINDS = {
63
+ type: 'type',
64
+ component: 'component',
65
+ dynamicZone: 'dynamic-zone',
66
+ enum: 'enum',
67
+ entity: 'entity',
68
+ entityResponse: 'entity-response',
69
+ entityResponseCollection: 'entity-response-collection',
70
+ relationResponseCollection: 'relation-response-collection',
71
+ query: 'query',
72
+ mutation: 'mutation',
73
+ input: 'input',
74
+ filtersInput: 'filters-input',
75
+ scalar: 'scalar',
76
+ morph: 'polymorphic',
77
+ internal: 'internal',
78
+ };
79
+
80
+ const allOperators = [
81
+ 'and',
82
+ 'or',
83
+ 'not',
84
+
85
+ 'eq',
86
+ 'ne',
87
+
88
+ 'startsWith',
89
+ 'endsWith',
90
+
91
+ 'contains',
92
+ 'notContains',
93
+
94
+ 'containsi',
95
+ 'notContainsi',
96
+
97
+ 'gt',
98
+ 'gte',
99
+
100
+ 'lt',
101
+ 'lte',
102
+
103
+ 'null',
104
+ 'notNull',
105
+
106
+ 'in',
107
+ 'notIn',
108
+
109
+ 'between',
110
+ ];
111
+
112
+ const GRAPHQL_SCALAR_OPERATORS = {
113
+ // ID
114
+ ID: allOperators,
115
+ // Booleans
116
+ Boolean: allOperators,
117
+ // Strings
118
+ String: allOperators,
119
+ // Numbers
120
+ Int: allOperators,
121
+ Long: allOperators,
122
+ Float: allOperators,
123
+ // Dates
124
+ Date: allOperators,
125
+ Time: allOperators,
126
+ DateTime: allOperators,
127
+ // Others
128
+ JSON: allOperators,
129
+ };
130
+
131
+ const ERROR_CODES = {
132
+ emptyDynamicZone: 'dynamiczone.empty',
133
+ };
134
+
135
+ module.exports = () => ({
136
+ PAGINATION_TYPE_NAME,
137
+ RESPONSE_COLLECTION_META_TYPE_NAME,
138
+ PUBLICATION_STATE_TYPE_NAME,
139
+ GRAPHQL_SCALARS,
140
+ STRAPI_SCALARS,
141
+ GENERIC_MORPH_TYPENAME,
142
+ KINDS,
143
+ GRAPHQL_SCALAR_OPERATORS,
144
+ SCALARS_ASSOCIATIONS,
145
+ ERROR_CODES,
146
+ ERROR_TYPE_NAME,
147
+ });