@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.
- package/admin/src/translations/zh-Hans.json +4 -0
- package/package.json +17 -15
- package/server/bootstrap.js +124 -0
- package/server/services/builders/dynamic-zones.js +96 -0
- package/server/services/builders/entity-meta.js +7 -0
- package/server/services/builders/entity.js +43 -0
- package/server/services/builders/enums.js +24 -0
- package/server/services/builders/filters/content-type.js +84 -0
- package/server/services/builders/filters/index.js +7 -0
- package/server/services/builders/filters/operators/and.js +15 -0
- package/server/services/builders/filters/operators/between.js +15 -0
- package/server/services/builders/filters/operators/contains.js +13 -0
- package/server/services/builders/filters/operators/containsi.js +13 -0
- package/server/services/builders/filters/operators/ends-with.js +13 -0
- package/server/services/builders/filters/operators/eq.js +19 -0
- package/server/services/builders/filters/operators/gt.js +13 -0
- package/server/services/builders/filters/operators/gte.js +13 -0
- package/server/services/builders/filters/operators/in.js +15 -0
- package/server/services/builders/filters/operators/index.js +38 -0
- package/server/services/builders/filters/operators/lt.js +13 -0
- package/server/services/builders/filters/operators/lte.js +13 -0
- package/server/services/builders/filters/operators/ne.js +13 -0
- package/server/services/builders/filters/operators/not-contains.js +13 -0
- package/server/services/builders/filters/operators/not-containsi.js +13 -0
- package/server/services/builders/filters/operators/not-in.js +15 -0
- package/server/services/builders/filters/operators/not-null.js +13 -0
- package/server/services/builders/filters/operators/not.js +19 -0
- package/server/services/builders/filters/operators/null.js +13 -0
- package/server/services/builders/filters/operators/or.js +15 -0
- package/server/services/builders/filters/operators/starts-with.js +13 -0
- package/server/services/builders/generic-morph.js +41 -0
- package/server/services/builders/index.js +92 -0
- package/server/services/builders/input.js +118 -0
- package/server/services/builders/mutations/collection-type.js +170 -0
- package/server/services/builders/mutations/index.js +9 -0
- package/server/services/builders/mutations/single-type.js +135 -0
- package/server/services/builders/queries/collection-type.js +120 -0
- package/server/services/builders/queries/index.js +9 -0
- package/server/services/builders/queries/single-type.js +70 -0
- package/server/services/builders/relation-response-collection.js +35 -0
- package/server/services/builders/resolvers/association.js +64 -0
- package/server/services/builders/resolvers/component.js +14 -0
- package/server/services/builders/resolvers/dynamic-zone.js +9 -0
- package/server/services/builders/resolvers/index.js +18 -0
- package/server/services/builders/resolvers/mutation.js +33 -0
- package/server/services/builders/resolvers/query.js +19 -0
- package/server/services/builders/response-collection.js +43 -0
- package/server/services/builders/response.js +32 -0
- package/server/services/builders/type.js +370 -0
- package/server/services/builders/utils.js +131 -0
- package/server/services/constants.js +147 -0
- package/server/services/content-api/index.js +168 -0
- package/server/services/content-api/policy.js +59 -0
- package/server/services/content-api/register-functions/collection-type.js +72 -0
- package/server/services/content-api/register-functions/component.js +15 -0
- package/server/services/content-api/register-functions/content-type/dynamic-zones.js +36 -0
- package/server/services/content-api/register-functions/content-type/enums.js +33 -0
- package/server/services/content-api/register-functions/content-type/filters.js +15 -0
- package/server/services/content-api/register-functions/content-type/index.js +13 -0
- package/server/services/content-api/register-functions/content-type/inputs.js +21 -0
- package/server/services/content-api/register-functions/index.js +22 -0
- package/server/services/content-api/register-functions/internals.js +13 -0
- package/server/services/content-api/register-functions/polymorphic.js +69 -0
- package/server/services/content-api/register-functions/scalars.js +14 -0
- package/server/services/content-api/register-functions/single-type.js +72 -0
- package/server/services/content-api/wrap-resolvers.js +146 -0
- package/server/services/extension/extension.js +95 -0
- package/server/services/extension/index.js +5 -0
- package/server/services/extension/shadow-crud-manager.js +159 -0
- package/server/services/format/index.js +7 -0
- package/server/services/format/return-types.js +27 -0
- package/server/services/index.js +21 -0
- package/server/services/internals/args/index.js +11 -0
- package/server/services/internals/args/pagination.js +19 -0
- package/server/services/internals/args/publication-state.js +12 -0
- package/server/services/internals/args/sort.js +10 -0
- package/server/services/internals/helpers/get-enabled-scalars.js +15 -0
- package/server/services/internals/helpers/index.js +7 -0
- package/server/services/internals/index.js +13 -0
- package/server/services/internals/scalars/index.js +18 -0
- package/server/services/internals/scalars/time.js +35 -0
- package/server/services/internals/types/error.js +33 -0
- package/server/services/internals/types/filters.js +39 -0
- package/server/services/internals/types/index.js +29 -0
- package/server/services/internals/types/pagination.js +24 -0
- package/server/services/internals/types/publication-state.js +24 -0
- package/server/services/internals/types/response-collection-meta.js +38 -0
- package/server/services/type-registry.js +103 -0
- package/server/services/utils/attributes.js +84 -0
- package/server/services/utils/index.js +11 -0
- package/server/services/utils/mappers/entity-to-response-entity.js +12 -0
- package/server/services/utils/mappers/graphql-filters-to-strapi-query.js +107 -0
- package/server/services/utils/mappers/graphql-scalar-to-operators.js +17 -0
- package/server/services/utils/mappers/index.js +13 -0
- package/server/services/utils/mappers/strapi-scalar-to-graphql-scalar.js +24 -0
- package/server/services/utils/naming.js +282 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +11 -0
- package/config/routes.json +0 -3
- package/config/schema.graphql +0 -1
- package/config/settings.json +0 -12
- package/controllers/GraphQL.js +0 -9
- package/hooks/graphql/defaults.json +0 -5
- package/hooks/graphql/index.js +0 -174
- package/hooks/graphql/load-config.js +0 -42
- package/services/build-aggregation.js +0 -565
- package/services/data-loaders.js +0 -55
- package/services/naming.js +0 -15
- package/services/resolvers-builder.js +0 -204
- package/services/schema-definitions.js +0 -131
- package/services/schema-generator.js +0 -178
- package/services/shadow-crud.js +0 -612
- package/services/type-builder.js +0 -311
- package/services/utils.js +0 -200
- package/types/dynamiczoneScalar.js +0 -40
- package/types/publication-state.js +0 -16
- package/types/time.js +0 -26
package/services/type-builder.js
DELETED
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Types.js service
|
|
5
|
-
*
|
|
6
|
-
* @description: A set of functions to make the schema easier to build.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const _ = require('lodash');
|
|
10
|
-
const { GraphQLUpload } = require('graphql-upload');
|
|
11
|
-
const graphql = require('graphql');
|
|
12
|
-
const { GraphQLJSON } = require('graphql-type-json');
|
|
13
|
-
const { GraphQLDate, GraphQLDateTime } = require('graphql-iso-date');
|
|
14
|
-
const GraphQLLong = require('graphql-type-long');
|
|
15
|
-
|
|
16
|
-
const Time = require('../types/time');
|
|
17
|
-
const { toSingular, toInputName } = require('./naming');
|
|
18
|
-
|
|
19
|
-
const isScalarAttribute = ({ type }) => type && !['component', 'dynamiczone'].includes(type);
|
|
20
|
-
const isTypeAttributeEnabled = (model, attr) =>
|
|
21
|
-
_.get(strapi.plugins.graphql, `config._schema.graphql.type.${model.globalId}.${attr}`) !== false;
|
|
22
|
-
|
|
23
|
-
module.exports = {
|
|
24
|
-
/**
|
|
25
|
-
* Convert Strapi type to GraphQL type.
|
|
26
|
-
* @param {Object} attribute Information about the attribute.
|
|
27
|
-
* @param {Object} attribute.definition Definition of the attribute.
|
|
28
|
-
* @param {String} attribute.modelName Name of the model which owns the attribute.
|
|
29
|
-
* @param {String} attribute.attributeName Name of the attribute.
|
|
30
|
-
* @return String
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
convertType({
|
|
34
|
-
attribute = {},
|
|
35
|
-
modelName = '',
|
|
36
|
-
attributeName = '',
|
|
37
|
-
rootType = 'query',
|
|
38
|
-
action = '',
|
|
39
|
-
}) {
|
|
40
|
-
// Type
|
|
41
|
-
if (isScalarAttribute(attribute)) {
|
|
42
|
-
let type = 'String';
|
|
43
|
-
|
|
44
|
-
switch (attribute.type) {
|
|
45
|
-
case 'boolean':
|
|
46
|
-
type = 'Boolean';
|
|
47
|
-
break;
|
|
48
|
-
case 'integer':
|
|
49
|
-
type = 'Int';
|
|
50
|
-
break;
|
|
51
|
-
case 'biginteger':
|
|
52
|
-
type = 'Long';
|
|
53
|
-
break;
|
|
54
|
-
case 'float':
|
|
55
|
-
case 'decimal':
|
|
56
|
-
type = 'Float';
|
|
57
|
-
break;
|
|
58
|
-
case 'json':
|
|
59
|
-
type = 'JSON';
|
|
60
|
-
break;
|
|
61
|
-
case 'date':
|
|
62
|
-
type = 'Date';
|
|
63
|
-
break;
|
|
64
|
-
case 'time':
|
|
65
|
-
type = 'Time';
|
|
66
|
-
break;
|
|
67
|
-
case 'datetime':
|
|
68
|
-
case 'timestamp':
|
|
69
|
-
type = 'DateTime';
|
|
70
|
-
break;
|
|
71
|
-
case 'enumeration':
|
|
72
|
-
type = this.convertEnumType(attribute, modelName, attributeName);
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (attribute.required) {
|
|
77
|
-
if (rootType !== 'mutation' || (action !== 'update' && attribute.default === undefined)) {
|
|
78
|
-
type += '!';
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return type;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (attribute.type === 'component') {
|
|
86
|
-
const { required, repeatable, component } = attribute;
|
|
87
|
-
|
|
88
|
-
const globalId = strapi.components[component].globalId;
|
|
89
|
-
|
|
90
|
-
let typeName = required === true ? `${globalId}` : globalId;
|
|
91
|
-
|
|
92
|
-
if (rootType === 'mutation') {
|
|
93
|
-
typeName =
|
|
94
|
-
action === 'update'
|
|
95
|
-
? `edit${_.upperFirst(toSingular(globalId))}Input`
|
|
96
|
-
: `${_.upperFirst(toSingular(globalId))}Input${required ? '!' : ''}`;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (repeatable === true) {
|
|
100
|
-
return `[${typeName}]`;
|
|
101
|
-
}
|
|
102
|
-
return `${typeName}`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (attribute.type === 'dynamiczone') {
|
|
106
|
-
const { required } = attribute;
|
|
107
|
-
|
|
108
|
-
const unionName = `${modelName}${_.upperFirst(_.camelCase(attributeName))}DynamicZone`;
|
|
109
|
-
|
|
110
|
-
let typeName = unionName;
|
|
111
|
-
|
|
112
|
-
if (rootType === 'mutation') {
|
|
113
|
-
typeName = `${unionName}Input!`;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return `[${typeName}]${required ? '!' : ''}`;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const ref = attribute.target;
|
|
120
|
-
|
|
121
|
-
// Association
|
|
122
|
-
if (ref && ref !== '*') {
|
|
123
|
-
// Add bracket or not
|
|
124
|
-
const globalId = strapi.getModel(ref).globalId;
|
|
125
|
-
const plural = !_.isEmpty(attribute.collection);
|
|
126
|
-
|
|
127
|
-
if (plural) {
|
|
128
|
-
if (rootType === 'mutation') {
|
|
129
|
-
return '[ID]';
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return `[${globalId}]`;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (rootType === 'mutation') {
|
|
136
|
-
return 'ID';
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return globalId;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (rootType === 'mutation') {
|
|
143
|
-
return attribute.model ? 'ID' : '[ID]';
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return attribute.model ? 'Morph' : '[Morph]';
|
|
147
|
-
},
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Convert Strapi enumeration to GraphQL Enum.
|
|
151
|
-
* @param {Object} definition Definition of the attribute.
|
|
152
|
-
* @param {String} model Name of the model which owns the attribute.
|
|
153
|
-
* @param {String} field Name of the attribute.
|
|
154
|
-
* @return String
|
|
155
|
-
*/
|
|
156
|
-
|
|
157
|
-
convertEnumType(definition, model, field) {
|
|
158
|
-
return definition.enumName
|
|
159
|
-
? definition.enumName
|
|
160
|
-
: `ENUM_${model.toUpperCase()}_${field.toUpperCase()}`;
|
|
161
|
-
},
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Add custom scalar type such as JSON.
|
|
165
|
-
*
|
|
166
|
-
* @return void
|
|
167
|
-
*/
|
|
168
|
-
|
|
169
|
-
getScalars() {
|
|
170
|
-
return {
|
|
171
|
-
JSON: GraphQLJSON,
|
|
172
|
-
DateTime: GraphQLDateTime,
|
|
173
|
-
Time,
|
|
174
|
-
Date: GraphQLDate,
|
|
175
|
-
Long: GraphQLLong,
|
|
176
|
-
Upload: GraphQLUpload,
|
|
177
|
-
};
|
|
178
|
-
},
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Add Union Type that contains the types defined by the user.
|
|
182
|
-
*
|
|
183
|
-
* @return string
|
|
184
|
-
*/
|
|
185
|
-
|
|
186
|
-
addPolymorphicUnionType(definition) {
|
|
187
|
-
const types = graphql
|
|
188
|
-
.parse(definition)
|
|
189
|
-
.definitions.filter(def => def.kind === 'ObjectTypeDefinition' && def.name.value !== 'Query')
|
|
190
|
-
.map(def => def.name.value);
|
|
191
|
-
|
|
192
|
-
if (types.length > 0) {
|
|
193
|
-
return {
|
|
194
|
-
definition: `union Morph = ${types.join(' | ')}`,
|
|
195
|
-
resolvers: {
|
|
196
|
-
Morph: {
|
|
197
|
-
__resolveType(obj) {
|
|
198
|
-
return obj.kind || obj.__contentType || null;
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return {
|
|
206
|
-
definition: '',
|
|
207
|
-
resolvers: {},
|
|
208
|
-
};
|
|
209
|
-
},
|
|
210
|
-
|
|
211
|
-
addInput() {
|
|
212
|
-
return `
|
|
213
|
-
input InputID { id: ID!}
|
|
214
|
-
`;
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
generateInputModel(model, name, { allowIds = false } = {}) {
|
|
218
|
-
const globalId = model.globalId;
|
|
219
|
-
const inputName = `${_.upperFirst(toSingular(name))}Input`;
|
|
220
|
-
const hasAllAttributesDisabled = Object.keys(model.attributes).every(
|
|
221
|
-
attr => !isTypeAttributeEnabled(model, attr)
|
|
222
|
-
);
|
|
223
|
-
|
|
224
|
-
if (_.isEmpty(model.attributes) || hasAllAttributesDisabled) {
|
|
225
|
-
return `
|
|
226
|
-
input ${inputName} {
|
|
227
|
-
_: String
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
input edit${inputName} {
|
|
231
|
-
${allowIds ? 'id: ID' : '_: String'}
|
|
232
|
-
}
|
|
233
|
-
`;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const inputs = `
|
|
237
|
-
input ${inputName} {
|
|
238
|
-
|
|
239
|
-
${Object.keys(model.attributes)
|
|
240
|
-
.filter(attributeName => isTypeAttributeEnabled(model, attributeName))
|
|
241
|
-
.map(attributeName => {
|
|
242
|
-
return `${attributeName}: ${this.convertType({
|
|
243
|
-
attribute: model.attributes[attributeName],
|
|
244
|
-
modelName: globalId,
|
|
245
|
-
attributeName,
|
|
246
|
-
rootType: 'mutation',
|
|
247
|
-
})}`;
|
|
248
|
-
})
|
|
249
|
-
.join('\n')}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
input edit${inputName} {
|
|
253
|
-
${allowIds ? 'id: ID' : ''}
|
|
254
|
-
${Object.keys(model.attributes)
|
|
255
|
-
.filter(attributeName => isTypeAttributeEnabled(model, attributeName))
|
|
256
|
-
.map(attributeName => {
|
|
257
|
-
return `${attributeName}: ${this.convertType({
|
|
258
|
-
attribute: model.attributes[attributeName],
|
|
259
|
-
modelName: globalId,
|
|
260
|
-
attributeName,
|
|
261
|
-
rootType: 'mutation',
|
|
262
|
-
action: 'update',
|
|
263
|
-
})}`;
|
|
264
|
-
})
|
|
265
|
-
.join('\n')}
|
|
266
|
-
}
|
|
267
|
-
`;
|
|
268
|
-
|
|
269
|
-
return inputs;
|
|
270
|
-
},
|
|
271
|
-
|
|
272
|
-
generateInputPayloadArguments({ model, name, mutationName, action }) {
|
|
273
|
-
const singularName = toSingular(name);
|
|
274
|
-
const inputName = toInputName(name);
|
|
275
|
-
|
|
276
|
-
const { kind } = model;
|
|
277
|
-
|
|
278
|
-
switch (action) {
|
|
279
|
-
case 'create':
|
|
280
|
-
return `
|
|
281
|
-
input ${mutationName}Input { data: ${inputName} }
|
|
282
|
-
type ${mutationName}Payload { ${singularName}: ${model.globalId} }
|
|
283
|
-
`;
|
|
284
|
-
case 'update':
|
|
285
|
-
if (kind === 'singleType') {
|
|
286
|
-
return `
|
|
287
|
-
input ${mutationName}Input { data: edit${inputName} }
|
|
288
|
-
type ${mutationName}Payload { ${singularName}: ${model.globalId} }
|
|
289
|
-
`;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
return `
|
|
293
|
-
input ${mutationName}Input { where: InputID, data: edit${inputName} }
|
|
294
|
-
type ${mutationName}Payload { ${singularName}: ${model.globalId} }
|
|
295
|
-
`;
|
|
296
|
-
case 'delete':
|
|
297
|
-
if (kind === 'singleType') {
|
|
298
|
-
return `
|
|
299
|
-
type ${mutationName}Payload { ${singularName}: ${model.globalId} }
|
|
300
|
-
`;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return `
|
|
304
|
-
input ${mutationName}Input { where: InputID }
|
|
305
|
-
type ${mutationName}Payload { ${singularName}: ${model.globalId} }
|
|
306
|
-
`;
|
|
307
|
-
default:
|
|
308
|
-
// Nothing
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
};
|
package/services/utils.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const _ = require('lodash');
|
|
4
|
-
const { QUERY_OPERATORS } = require('@strapi/utils');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @typedef {object} Schema
|
|
8
|
-
* @property {object} resolvers
|
|
9
|
-
* @property {object} mutation
|
|
10
|
-
* @property {object} query
|
|
11
|
-
* @property {string} definition
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Merges strapi graphql schema together
|
|
16
|
-
* @param {Schema} object - destination object
|
|
17
|
-
* @param {Schema[]} sources - source objects to merge into the destination object
|
|
18
|
-
* @returns {Schema}
|
|
19
|
-
*/
|
|
20
|
-
const mergeSchemas = (object, ...sources) => {
|
|
21
|
-
sources.forEach(sub => {
|
|
22
|
-
if (_.isEmpty(sub)) return;
|
|
23
|
-
const { definition = '', query = {}, mutation = {}, resolvers = {} } = sub;
|
|
24
|
-
|
|
25
|
-
object.definition += '\n' + definition;
|
|
26
|
-
_.merge(object, {
|
|
27
|
-
query,
|
|
28
|
-
mutation,
|
|
29
|
-
resolvers,
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
return object;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Returns an empty schema
|
|
38
|
-
* @returns {Schema}
|
|
39
|
-
*/
|
|
40
|
-
const createDefaultSchema = () => ({
|
|
41
|
-
definition: '',
|
|
42
|
-
query: {},
|
|
43
|
-
mutation: {},
|
|
44
|
-
resolvers: {},
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const diffResolvers = (object, base) => {
|
|
48
|
-
let newObj = {};
|
|
49
|
-
|
|
50
|
-
Object.keys(object).forEach(type => {
|
|
51
|
-
Object.keys(object[type]).forEach(resolver => {
|
|
52
|
-
if (type === 'Query' || type === 'Mutation') {
|
|
53
|
-
if (!_.has(base, [type, resolver])) {
|
|
54
|
-
_.set(newObj, [type, resolver], _.get(object, [type, resolver]));
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
_.set(newObj, [type, resolver], _.get(object, [type, resolver]));
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
return newObj;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const convertToParams = params => {
|
|
66
|
-
return Object.keys(params).reduce((acc, current) => {
|
|
67
|
-
const key = current === 'id' ? 'id' : `_${current}`;
|
|
68
|
-
acc[key] = params[current];
|
|
69
|
-
return acc;
|
|
70
|
-
}, {});
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const convertToQuery = params => {
|
|
74
|
-
const result = {};
|
|
75
|
-
|
|
76
|
-
_.forEach(params, (value, key) => {
|
|
77
|
-
if (QUERY_OPERATORS.includes(key)) {
|
|
78
|
-
result[key] = _.isArray(value) ? value.map(convertToQuery) : convertToQuery(value);
|
|
79
|
-
} else if (_.isPlainObject(value)) {
|
|
80
|
-
const flatObject = convertToQuery(value);
|
|
81
|
-
_.forEach(flatObject, (_value, _key) => {
|
|
82
|
-
result[`${key}.${_key}`] = _value;
|
|
83
|
-
});
|
|
84
|
-
} else {
|
|
85
|
-
result[key] = value;
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
return result;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const amountLimiting = (params = {}) => {
|
|
93
|
-
const { amountLimit } = strapi.plugins.graphql.config;
|
|
94
|
-
|
|
95
|
-
if (!amountLimit) return params;
|
|
96
|
-
|
|
97
|
-
if (_.isNil(params.limit) || params.limit === -1 || params.limit > amountLimit) {
|
|
98
|
-
params.limit = amountLimit;
|
|
99
|
-
} else if (params.limit < 0) {
|
|
100
|
-
params.limit = 0;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return params;
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const nonRequired = type => type.replace('!', '');
|
|
107
|
-
|
|
108
|
-
const actionExists = ({ resolver, resolverOf }) => {
|
|
109
|
-
if (isResolvablePath(resolverOf)) {
|
|
110
|
-
return true;
|
|
111
|
-
} else if (_.isFunction(resolver)) {
|
|
112
|
-
return true;
|
|
113
|
-
} else if (_.isString(resolver)) {
|
|
114
|
-
return _.isFunction(getActionFn(getActionDetails(resolver)));
|
|
115
|
-
} else {
|
|
116
|
-
throw new Error(
|
|
117
|
-
`Error building query. Expected \`resolver\` as string or a function, or \`resolverOf\` as a string. got ${{
|
|
118
|
-
resolver,
|
|
119
|
-
resolverOf,
|
|
120
|
-
}}`
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const getAction = resolver => {
|
|
126
|
-
if (!_.isString(resolver)) {
|
|
127
|
-
throw new Error(`Error building query. Expected a string, got ${resolver}`);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const actionDetails = getActionDetails(resolver);
|
|
131
|
-
const actionFn = getActionFn(actionDetails);
|
|
132
|
-
|
|
133
|
-
if (!actionFn) {
|
|
134
|
-
throw new Error(
|
|
135
|
-
`[GraphQL] Cannot find action "${resolver}". Check your graphql configurations.`
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return actionFn;
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const getActionFn = details => {
|
|
143
|
-
const { controller, action, plugin, api } = details;
|
|
144
|
-
|
|
145
|
-
if (plugin) {
|
|
146
|
-
return _.get(strapi.plugins, [_.toLower(plugin), 'controllers', _.toLower(controller), action]);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return _.get(strapi.api, [_.toLower(api), 'controllers', _.toLower(controller), action]);
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const getActionDetails = resolver => {
|
|
153
|
-
if (resolver.startsWith('plugins::')) {
|
|
154
|
-
const [, path] = resolver.split('::');
|
|
155
|
-
const [plugin, controller, action] = path.split('.');
|
|
156
|
-
|
|
157
|
-
return { plugin, controller, action };
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (resolver.startsWith('application::')) {
|
|
161
|
-
const [, path] = resolver.split('::');
|
|
162
|
-
const [api, controller, action] = path.split('.');
|
|
163
|
-
|
|
164
|
-
return { api, controller, action };
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const args = resolver.split('.');
|
|
168
|
-
|
|
169
|
-
if (args.length === 3) {
|
|
170
|
-
const [api, controller, action] = args;
|
|
171
|
-
return { api, controller, action };
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// if direct api access
|
|
175
|
-
if (args.length === 2) {
|
|
176
|
-
const [controller, action] = args;
|
|
177
|
-
return { api: controller, controller, action };
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
throw new Error(
|
|
181
|
-
`[GraphQL] Could not find action for resolver "${resolver}". Check your graphql configurations.`
|
|
182
|
-
);
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
const isResolvablePath = path => _.isString(path) && !_.isEmpty(path);
|
|
186
|
-
|
|
187
|
-
module.exports = {
|
|
188
|
-
diffResolvers,
|
|
189
|
-
mergeSchemas,
|
|
190
|
-
createDefaultSchema,
|
|
191
|
-
convertToParams,
|
|
192
|
-
convertToQuery,
|
|
193
|
-
amountLimiting,
|
|
194
|
-
nonRequired,
|
|
195
|
-
actionExists,
|
|
196
|
-
getAction,
|
|
197
|
-
getActionDetails,
|
|
198
|
-
getActionFn,
|
|
199
|
-
isResolvablePath,
|
|
200
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const _ = require('lodash');
|
|
4
|
-
const { Kind, GraphQLScalarType, valueFromASTUntyped, GraphQLError } = require('graphql');
|
|
5
|
-
|
|
6
|
-
module.exports = function DynamicZoneScalar({ name, attribute, globalId, components }) {
|
|
7
|
-
const parseData = value => {
|
|
8
|
-
const compo = Object.values(strapi.components).find(
|
|
9
|
-
compo => compo.globalId === value.__typename
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
if (!compo) {
|
|
13
|
-
throw new GraphQLError(
|
|
14
|
-
`Component not found. expected one of: ${components
|
|
15
|
-
.map(uid => strapi.components[uid].globalId)
|
|
16
|
-
.join(', ')}`
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const finalValue = {
|
|
21
|
-
__component: compo.uid,
|
|
22
|
-
..._.omit(value, ['__typename']),
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
return finalValue;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
return new GraphQLScalarType({
|
|
29
|
-
name: name,
|
|
30
|
-
description: `Input type for dynamic zone ${attribute} of ${globalId}`,
|
|
31
|
-
serialize: value => value,
|
|
32
|
-
parseValue: value => parseData(value),
|
|
33
|
-
parseLiteral: (ast, variables) => {
|
|
34
|
-
if (ast.kind !== Kind.OBJECT) return undefined;
|
|
35
|
-
|
|
36
|
-
const value = valueFromASTUntyped(ast, variables);
|
|
37
|
-
return parseData(value);
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
};
|
package/types/time.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { parseType } = require('@strapi/utils');
|
|
4
|
-
|
|
5
|
-
const { Kind, GraphQLScalarType } = require('graphql');
|
|
6
|
-
|
|
7
|
-
const Time = new GraphQLScalarType({
|
|
8
|
-
name: 'Time',
|
|
9
|
-
description: 'A time string with format: HH:mm:ss.SSS',
|
|
10
|
-
serialize(value) {
|
|
11
|
-
return parseType({ type: 'time', value });
|
|
12
|
-
},
|
|
13
|
-
parseValue(value) {
|
|
14
|
-
return parseType({ type: 'time', value });
|
|
15
|
-
},
|
|
16
|
-
parseLiteral(ast) {
|
|
17
|
-
if (ast.kind !== Kind.STRING) {
|
|
18
|
-
throw new TypeError(`Time cannot represent non string type`);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const value = ast.value;
|
|
22
|
-
return parseType({ type: 'time', value });
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
module.exports = Time;
|