@strapi/plugin-graphql 4.0.0-next.8 → 4.0.2
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/README.md +1 -1
- package/admin/src/index.js +0 -8
- package/package.json +43 -35
- package/server/bootstrap.js +148 -0
- package/server/config/default-config.js +13 -0
- package/server/config/index.js +7 -0
- package/server/format-graphql-error.js +50 -0
- package/server/services/builders/dynamic-zones.js +97 -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 +93 -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 +23 -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 +121 -0
- package/server/services/builders/mutations/collection-type.js +191 -0
- package/server/services/builders/mutations/index.js +9 -0
- package/server/services/builders/mutations/single-type.js +141 -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 +85 -0
- package/server/services/builders/resolvers/component.js +18 -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 +364 -0
- package/server/services/builders/utils.js +134 -0
- package/server/services/constants.js +149 -0
- package/server/services/content-api/index.js +179 -0
- package/server/services/content-api/policy.js +60 -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 +144 -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 +36 -0
- package/server/services/internals/types/error.js +34 -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 +39 -0
- package/server/services/type-registry.js +104 -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 +109 -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 +25 -0
- package/server/services/utils/naming.js +287 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +7 -9
- package/admin/src/assets/images/logo.svg +0 -38
- 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
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { camelCase, upperFirst, lowerFirst, pipe, get } = require('lodash/fp');
|
|
4
|
+
const { singular } = require('pluralize');
|
|
5
|
+
const { ApplicationError } = require('@strapi/utils').errors;
|
|
6
|
+
|
|
7
|
+
module.exports = ({ strapi }) => {
|
|
8
|
+
/**
|
|
9
|
+
* Build a type name for a enum based on a content type & an attribute name
|
|
10
|
+
* @param {object} contentType
|
|
11
|
+
* @param {string} attributeName
|
|
12
|
+
* @return {string}
|
|
13
|
+
*/
|
|
14
|
+
const getEnumName = (contentType, attributeName) => {
|
|
15
|
+
const { attributes } = contentType;
|
|
16
|
+
const { enumName } = attributes[attributeName];
|
|
17
|
+
const { modelType } = contentType;
|
|
18
|
+
|
|
19
|
+
const typeName =
|
|
20
|
+
modelType === 'component' ? getComponentName(contentType) : getTypeName(contentType);
|
|
21
|
+
|
|
22
|
+
const defaultEnumName = `ENUM_${typeName.toUpperCase()}_${attributeName.toUpperCase()}`;
|
|
23
|
+
|
|
24
|
+
return enumName || defaultEnumName;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Build the base type name for a given content type
|
|
29
|
+
* @param {object} contentType
|
|
30
|
+
* @param {object} options
|
|
31
|
+
* @param {'singular' | 'plural'} options.plurality
|
|
32
|
+
* @return {string}
|
|
33
|
+
*/
|
|
34
|
+
const getTypeName = (contentType, { plurality = 'singular' } = {}) => {
|
|
35
|
+
const plugin = get('plugin', contentType);
|
|
36
|
+
const modelName = get('modelName', contentType);
|
|
37
|
+
const name =
|
|
38
|
+
plurality === 'singular'
|
|
39
|
+
? get('info.singularName', contentType)
|
|
40
|
+
: get('info.pluralName', contentType);
|
|
41
|
+
|
|
42
|
+
const transformedPlugin = upperFirst(camelCase(plugin));
|
|
43
|
+
const transformedModelName = upperFirst(camelCase(name || singular(modelName)));
|
|
44
|
+
|
|
45
|
+
return `${transformedPlugin}${transformedModelName}`;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Build the entity's type name for a given content type
|
|
50
|
+
* @param {object} contentType
|
|
51
|
+
* @return {string}
|
|
52
|
+
*/
|
|
53
|
+
const getEntityName = contentType => {
|
|
54
|
+
return `${getTypeName(contentType)}Entity`;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Build the entity meta type name for a given content type
|
|
59
|
+
* @param {object} contentType
|
|
60
|
+
* @return {string}
|
|
61
|
+
*/
|
|
62
|
+
const getEntityMetaName = contentType => {
|
|
63
|
+
return `${getEntityName(contentType)}Meta`;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Build the entity response's type name for a given content type
|
|
68
|
+
* @param {object} contentType
|
|
69
|
+
* @return {string}
|
|
70
|
+
*/
|
|
71
|
+
const getEntityResponseName = contentType => {
|
|
72
|
+
return `${getEntityName(contentType)}Response`;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Build the entity response collection's type name for a given content type
|
|
77
|
+
* @param {object} contentType
|
|
78
|
+
* @return {string}
|
|
79
|
+
*/
|
|
80
|
+
const getEntityResponseCollectionName = contentType => {
|
|
81
|
+
return `${getEntityName(contentType)}ResponseCollection`;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Build the relation response collection's type name for a given content type
|
|
86
|
+
* @param {object} contentType
|
|
87
|
+
* @return {string}
|
|
88
|
+
*/
|
|
89
|
+
const getRelationResponseCollectionName = contentType => {
|
|
90
|
+
return `${getTypeName(contentType)}RelationResponseCollection`;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Build a component type name based on its definition
|
|
95
|
+
* @param {object} contentType
|
|
96
|
+
* @return {string}
|
|
97
|
+
*/
|
|
98
|
+
const getComponentName = contentType => {
|
|
99
|
+
return contentType.globalId;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Build a component type name based on a content type's attribute
|
|
104
|
+
* @param {object} attribute
|
|
105
|
+
* @return {string}
|
|
106
|
+
*/
|
|
107
|
+
const getComponentNameFromAttribute = attribute => {
|
|
108
|
+
return strapi.components[attribute.component].globalId;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Build a dynamic zone type name based on a content type and an attribute name
|
|
113
|
+
* @param {object} contentType
|
|
114
|
+
* @param {string} attributeName
|
|
115
|
+
* @return {string}
|
|
116
|
+
*/
|
|
117
|
+
const getDynamicZoneName = (contentType, attributeName) => {
|
|
118
|
+
const typeName = getTypeName(contentType);
|
|
119
|
+
const dzName = upperFirst(camelCase(attributeName));
|
|
120
|
+
const suffix = 'DynamicZone';
|
|
121
|
+
|
|
122
|
+
return `${typeName}${dzName}${suffix}`;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Build a dynamic zone input type name based on a content type and an attribute name
|
|
127
|
+
* @param {object} contentType
|
|
128
|
+
* @param {string} attributeName
|
|
129
|
+
* @return {string}
|
|
130
|
+
*/
|
|
131
|
+
const getDynamicZoneInputName = (contentType, attributeName) => {
|
|
132
|
+
const dzName = getDynamicZoneName(contentType, attributeName);
|
|
133
|
+
|
|
134
|
+
return `${dzName}Input`;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Build a component input type name based on a content type and an attribute name
|
|
139
|
+
* @param {object} contentType
|
|
140
|
+
* @return {string}
|
|
141
|
+
*/
|
|
142
|
+
const getComponentInputName = contentType => {
|
|
143
|
+
const componentName = getComponentName(contentType);
|
|
144
|
+
|
|
145
|
+
return `${componentName}Input`;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Build a content type input name based on a content type and an attribute name
|
|
150
|
+
* @param {object} contentType
|
|
151
|
+
* @return {string}
|
|
152
|
+
*/
|
|
153
|
+
const getContentTypeInputName = contentType => {
|
|
154
|
+
const typeName = getTypeName(contentType);
|
|
155
|
+
|
|
156
|
+
return `${typeName}Input`;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Build the queries type name for a given content type
|
|
161
|
+
* @param {object} contentType
|
|
162
|
+
* @return {string}
|
|
163
|
+
*/
|
|
164
|
+
const getEntityQueriesTypeName = contentType => {
|
|
165
|
+
return `${getEntityName(contentType)}Queries`;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Build the mutations type name for a given content type
|
|
170
|
+
* @param {object} contentType
|
|
171
|
+
* @return {string}
|
|
172
|
+
*/
|
|
173
|
+
const getEntityMutationsTypeName = contentType => {
|
|
174
|
+
return `${getEntityName(contentType)}Mutations`;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Build the filters type name for a given content type
|
|
179
|
+
* @param {object} contentType
|
|
180
|
+
* @return {string}
|
|
181
|
+
*/
|
|
182
|
+
const getFiltersInputTypeName = contentType => {
|
|
183
|
+
const isComponent = contentType.modelType === 'component';
|
|
184
|
+
|
|
185
|
+
const baseName = isComponent ? getComponentName(contentType) : getTypeName(contentType);
|
|
186
|
+
|
|
187
|
+
return `${baseName}FiltersInput`;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Build a filters type name for a given GraphQL scalar type
|
|
192
|
+
* @param {NexusGenScalars} scalarType
|
|
193
|
+
* @return {string}
|
|
194
|
+
*/
|
|
195
|
+
const getScalarFilterInputTypeName = scalarType => {
|
|
196
|
+
return `${scalarType}FilterInput`;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Build a type name for a given content type & polymorphic attribute
|
|
201
|
+
* @param {object} contentType
|
|
202
|
+
* @param {string} attributeName
|
|
203
|
+
* @return {string}
|
|
204
|
+
*/
|
|
205
|
+
const getMorphRelationTypeName = (contentType, attributeName) => {
|
|
206
|
+
const typeName = getTypeName(contentType);
|
|
207
|
+
const formattedAttr = upperFirst(camelCase(attributeName));
|
|
208
|
+
|
|
209
|
+
return `${typeName}${formattedAttr}Morph`;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Build a custom type name generator with different customization options
|
|
214
|
+
* @param {object} options
|
|
215
|
+
* @param {string} [options.prefix]
|
|
216
|
+
* @param {string} [options.suffix]
|
|
217
|
+
* @param {'upper' | 'lower'} [options.firstLetterCase]
|
|
218
|
+
* @param {'plural' | 'singular'} [options.plurality]
|
|
219
|
+
* @return {function(*=): string}
|
|
220
|
+
*/
|
|
221
|
+
const buildCustomTypeNameGenerator = (options = {}) => {
|
|
222
|
+
// todo[v4]: use singularName & pluralName is available
|
|
223
|
+
const { prefix = '', suffix = '', plurality = 'singular', firstLetterCase = 'upper' } = options;
|
|
224
|
+
|
|
225
|
+
if (!['plural', 'singular'].includes(plurality)) {
|
|
226
|
+
throw new ApplicationError(
|
|
227
|
+
`"plurality" param must be either "plural" or "singular", but got: "${plurality}"`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const getCustomTypeName = pipe(
|
|
232
|
+
ct => getTypeName(ct, { plurality }),
|
|
233
|
+
firstLetterCase === 'upper' ? upperFirst : lowerFirst
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
return contentType => `${prefix}${getCustomTypeName(contentType)}${suffix}`;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const getFindQueryName = buildCustomTypeNameGenerator({
|
|
240
|
+
plurality: 'plural',
|
|
241
|
+
firstLetterCase: 'lower',
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const getFindOneQueryName = buildCustomTypeNameGenerator({ firstLetterCase: 'lower' });
|
|
245
|
+
|
|
246
|
+
const getCreateMutationTypeName = buildCustomTypeNameGenerator({
|
|
247
|
+
prefix: 'create',
|
|
248
|
+
firstLetterCase: 'upper',
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const getUpdateMutationTypeName = buildCustomTypeNameGenerator({
|
|
252
|
+
prefix: 'update',
|
|
253
|
+
firstLetterCase: 'upper',
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const getDeleteMutationTypeName = buildCustomTypeNameGenerator({
|
|
257
|
+
prefix: 'delete',
|
|
258
|
+
firstLetterCase: 'upper',
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
getEnumName,
|
|
263
|
+
getTypeName,
|
|
264
|
+
getEntityName,
|
|
265
|
+
getEntityMetaName,
|
|
266
|
+
getEntityResponseName,
|
|
267
|
+
getEntityResponseCollectionName,
|
|
268
|
+
getRelationResponseCollectionName,
|
|
269
|
+
getComponentName,
|
|
270
|
+
getComponentNameFromAttribute,
|
|
271
|
+
getDynamicZoneName,
|
|
272
|
+
getDynamicZoneInputName,
|
|
273
|
+
getComponentInputName,
|
|
274
|
+
getContentTypeInputName,
|
|
275
|
+
getEntityQueriesTypeName,
|
|
276
|
+
getEntityMutationsTypeName,
|
|
277
|
+
getFiltersInputTypeName,
|
|
278
|
+
getScalarFilterInputTypeName,
|
|
279
|
+
getMorphRelationTypeName,
|
|
280
|
+
buildCustomTypeNameGenerator,
|
|
281
|
+
getFindQueryName,
|
|
282
|
+
getFindOneQueryName,
|
|
283
|
+
getCreateMutationTypeName,
|
|
284
|
+
getUpdateMutationTypeName,
|
|
285
|
+
getDeleteMutationTypeName,
|
|
286
|
+
};
|
|
287
|
+
};
|
package/strapi-admin.js
ADDED
package/strapi-server.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const bootstrap = require('./server/bootstrap');
|
|
4
|
+
const services = require('./server/services');
|
|
5
|
+
const config = require('./server/config');
|
|
6
|
+
|
|
3
7
|
module.exports = (/* strapi, config */) => {
|
|
4
8
|
return {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
routes: [],
|
|
9
|
-
controllers: {},
|
|
10
|
-
services: () => {},
|
|
11
|
-
policies: {},
|
|
12
|
-
middlewares: {},
|
|
13
|
-
contentTypes: {},
|
|
9
|
+
config,
|
|
10
|
+
bootstrap,
|
|
11
|
+
services,
|
|
14
12
|
};
|
|
15
13
|
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg width="25px" height="28px" viewBox="0 0 25 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
3
|
-
<!-- Generator: Sketch 46.1 (44463) - http://www.bohemiancoding.com/sketch -->
|
|
4
|
-
<title>GraphQL_Logo</title>
|
|
5
|
-
<desc>Created with Sketch.</desc>
|
|
6
|
-
<defs></defs>
|
|
7
|
-
<g id="Pages" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
8
|
-
<g id="List-plugins" transform="translate(-302.000000, -668.000000)" fill-rule="nonzero" fill="#E535AB">
|
|
9
|
-
<g id="Container" transform="translate(263.000000, 83.000000)">
|
|
10
|
-
<g id="Content">
|
|
11
|
-
<g id="Forms" transform="translate(1.000000, 78.000000)">
|
|
12
|
-
<g id="List" transform="translate(15.000000, 19.000000)">
|
|
13
|
-
<g id="9" transform="translate(0.000000, 484.000000)">
|
|
14
|
-
<g id="GraphQL_Logo" transform="translate(23.000000, 4.000000)">
|
|
15
|
-
<rect id="Rectangle-path" transform="translate(7.525343, 11.130007) rotate(-149.999272) translate(-7.525343, -11.130007) " x="6.93249876" y="-0.309026904" width="1.1856882" height="22.8780681"></rect>
|
|
16
|
-
<rect id="Rectangle-path" x="1.05714286" y="19.1571429" width="22.8785714" height="1.18571429"></rect>
|
|
17
|
-
<rect id="Rectangle-path" transform="translate(7.528064, 22.613421) rotate(-149.999272) translate(-7.528064, -22.613421) " x="0.921066787" y="22.0205773" width="13.213995" height="1.1856882"></rect>
|
|
18
|
-
<rect id="Rectangle-path" transform="translate(17.469093, 5.393493) rotate(-149.999272) translate(-17.469093, -5.393493) " x="10.8620954" y="4.80064876" width="13.213995" height="1.1856882"></rect>
|
|
19
|
-
<rect id="Rectangle-path" transform="translate(7.531236, 5.388979) rotate(-120.000728) translate(-7.531236, -5.388979) " x="6.93839161" y="-1.21801893" width="1.1856882" height="13.213995"></rect>
|
|
20
|
-
<rect id="Rectangle-path" transform="translate(17.477229, 11.130221) rotate(-120.000728) translate(-17.477229, -11.130221) " x="6.03819452" y="10.5373773" width="22.8780681" height="1.1856882"></rect>
|
|
21
|
-
<rect id="Rectangle-path" x="1.96428571" y="7.39285714" width="1.18571429" height="13.2142857"></rect>
|
|
22
|
-
<rect id="Rectangle-path" x="21.85" y="7.39285714" width="1.18571429" height="13.2142857"></rect>
|
|
23
|
-
<rect id="Rectangle-path" transform="translate(17.469043, 22.606829) rotate(-120.000728) translate(-17.469043, -22.606829) " x="16.9511971" y="16.8605264" width="1.0356915" height="11.4926043"></rect>
|
|
24
|
-
<path d="M24.6071429,20.9928571 C23.9214286,22.1857143 22.3928571,22.5928571 21.2,21.9071429 C20.0071429,21.2214286 19.6,19.6928571 20.2857143,18.5 C20.9714286,17.3071429 22.5,16.9 23.6928571,17.5857143 C24.8928571,18.2785714 25.3,19.8 24.6071429,20.9928571" id="Shape"></path>
|
|
25
|
-
<path d="M4.70714286,9.5 C4.02142857,10.6928571 2.49285714,11.1 1.3,10.4142857 C0.107142857,9.72857143 -0.3,8.2 0.385714286,7.00714286 C1.07142857,5.81428571 2.6,5.40714286 3.79285714,6.09285714 C4.98571429,6.78571429 5.39285714,8.30714286 4.70714286,9.5" id="Shape"></path>
|
|
26
|
-
<path d="M0.392857143,20.9928571 C-0.292857143,19.8 0.114285714,18.2785714 1.30714286,17.5857143 C2.5,16.9 4.02142857,17.3071429 4.71428571,18.5 C5.4,19.6928571 4.99285714,21.2142857 3.8,21.9071429 C2.6,22.5928571 1.07857143,22.1857143 0.392857143,20.9928571" id="Shape"></path>
|
|
27
|
-
<path d="M20.2928571,9.5 C19.6071429,8.30714286 20.0142857,6.78571429 21.2071429,6.09285714 C22.4,5.40714286 23.9214286,5.81428571 24.6142857,7.00714286 C25.3,8.2 24.8928571,9.72142857 23.7,10.4142857 C22.5071429,11.1 20.9785714,10.6928571 20.2928571,9.5" id="Shape"></path>
|
|
28
|
-
<path d="M12.5,27.9857143 C11.1214286,27.9857143 10.0071429,26.8714286 10.0071429,25.4928571 C10.0071429,24.1142857 11.1214286,23 12.5,23 C13.8785714,23 14.9928571,24.1142857 14.9928571,25.4928571 C14.9928571,26.8642857 13.8785714,27.9857143 12.5,27.9857143" id="Shape"></path>
|
|
29
|
-
<path d="M12.5,5 C11.1214286,5 10.0071429,3.88571429 10.0071429,2.50714286 C10.0071429,1.12857143 11.1214286,0.0142857143 12.5,0.0142857143 C13.8785714,0.0142857143 14.9928571,1.12857143 14.9928571,2.50714286 C14.9928571,3.88571429 13.8785714,5 12.5,5" id="Shape"></path>
|
|
30
|
-
</g>
|
|
31
|
-
</g>
|
|
32
|
-
</g>
|
|
33
|
-
</g>
|
|
34
|
-
</g>
|
|
35
|
-
</g>
|
|
36
|
-
</g>
|
|
37
|
-
</g>
|
|
38
|
-
</svg>
|
package/config/routes.json
DELETED
package/config/schema.graphql
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = {};
|
package/config/settings.json
DELETED
package/controllers/GraphQL.js
DELETED
package/hooks/graphql/index.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Module dependencies
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Public node modules.
|
|
8
|
-
const _ = require('lodash');
|
|
9
|
-
const { ApolloServer } = require('apollo-server-koa');
|
|
10
|
-
const depthLimit = require('graphql-depth-limit');
|
|
11
|
-
const { graphqlUploadKoa } = require('graphql-upload');
|
|
12
|
-
const loadConfigs = require('./load-config');
|
|
13
|
-
|
|
14
|
-
const attachMetadataToResolvers = (schema, { api, plugin }) => {
|
|
15
|
-
const { resolver = {} } = schema;
|
|
16
|
-
if (_.isEmpty(resolver)) return schema;
|
|
17
|
-
|
|
18
|
-
Object.keys(resolver).forEach(type => {
|
|
19
|
-
if (!_.isPlainObject(resolver[type])) return;
|
|
20
|
-
|
|
21
|
-
Object.keys(resolver[type]).forEach(resolverName => {
|
|
22
|
-
if (!_.isPlainObject(resolver[type][resolverName])) return;
|
|
23
|
-
|
|
24
|
-
resolver[type][resolverName]['_metadatas'] = {
|
|
25
|
-
api,
|
|
26
|
-
plugin,
|
|
27
|
-
};
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
return schema;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
module.exports = strapi => {
|
|
35
|
-
const { appPath, installedPlugins } = strapi.config;
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
async beforeInitialize() {
|
|
39
|
-
// Try to inject this hook just after the others hooks to skip the router processing.
|
|
40
|
-
if (!strapi.config.get('hook.load.after')) {
|
|
41
|
-
_.set(strapi.config.hook.load, 'after', []);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
strapi.config.hook.load.after.push('graphql');
|
|
45
|
-
// Load core utils.
|
|
46
|
-
|
|
47
|
-
const { api, plugins, extensions } = await loadConfigs({
|
|
48
|
-
appPath,
|
|
49
|
-
installedPlugins,
|
|
50
|
-
});
|
|
51
|
-
_.merge(strapi, { api, plugins });
|
|
52
|
-
|
|
53
|
-
// Create a merge of all the GraphQL configuration.
|
|
54
|
-
const apisSchemas = Object.keys(strapi.api || {}).map(key => {
|
|
55
|
-
const schema = _.get(strapi.api[key], 'config.schema.graphql', {});
|
|
56
|
-
return attachMetadataToResolvers(schema, { api: key });
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const pluginsSchemas = Object.keys(strapi.plugins || {}).map(key => {
|
|
60
|
-
const schema = _.get(strapi.plugins[key], 'config.schema.graphql', {});
|
|
61
|
-
return attachMetadataToResolvers(schema, { plugin: key });
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const extensionsSchemas = Object.keys(extensions || {}).map(key => {
|
|
65
|
-
const schema = _.get(extensions[key], 'config.schema.graphql', {});
|
|
66
|
-
return attachMetadataToResolvers(schema, { plugin: key });
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
const baseSchema = mergeSchemas([...pluginsSchemas, ...extensionsSchemas, ...apisSchemas]);
|
|
70
|
-
|
|
71
|
-
// save the final schema in the plugin's config
|
|
72
|
-
_.set(strapi.plugins.graphql, 'config._schema.graphql', baseSchema);
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
initialize() {
|
|
76
|
-
const schema = strapi.plugins.graphql.services['schema-generator'].generateSchema();
|
|
77
|
-
|
|
78
|
-
if (_.isEmpty(schema)) {
|
|
79
|
-
strapi.log.warn('The GraphQL schema has not been generated because it is empty');
|
|
80
|
-
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const config = _.get(strapi.plugins.graphql, 'config', {});
|
|
85
|
-
|
|
86
|
-
// TODO: Remove these deprecated options in favor of `apolloServer` in the next major version
|
|
87
|
-
const deprecatedApolloServerConfig = {
|
|
88
|
-
tracing: _.get(config, 'tracing', false),
|
|
89
|
-
introspection: _.get(config, 'introspection', true),
|
|
90
|
-
engine: _.get(config, 'engine', false),
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
if (['tracing', 'introspection', 'engine'].some(key => _.has(config, key))) {
|
|
94
|
-
strapi.log.warn(
|
|
95
|
-
'The `tracing`, `introspection` and `engine` options are deprecated in favor of the `apolloServer` object and they will be removed in the next major version.'
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const apolloServerConfig = _.get(config, 'apolloServer', {});
|
|
100
|
-
|
|
101
|
-
const serverParams = {
|
|
102
|
-
schema,
|
|
103
|
-
uploads: false,
|
|
104
|
-
context: ({ ctx }) => {
|
|
105
|
-
// Initiliase loaders for this request.
|
|
106
|
-
// TODO: set loaders in the context not globally
|
|
107
|
-
|
|
108
|
-
strapi.plugins.graphql.services['data-loaders'].initializeLoader();
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
context: ctx,
|
|
112
|
-
};
|
|
113
|
-
},
|
|
114
|
-
formatError: err => {
|
|
115
|
-
const formatError = _.get(config, 'formatError', null);
|
|
116
|
-
|
|
117
|
-
return typeof formatError === 'function' ? formatError(err) : err;
|
|
118
|
-
},
|
|
119
|
-
validationRules: [depthLimit(config.depthLimit)],
|
|
120
|
-
playground: false,
|
|
121
|
-
cors: false,
|
|
122
|
-
bodyParserConfig: true,
|
|
123
|
-
// TODO: Remove these deprecated options in favor of `apolloServerConfig` in the next major version
|
|
124
|
-
...deprecatedApolloServerConfig,
|
|
125
|
-
...apolloServerConfig,
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
// Disable GraphQL Playground in production environment.
|
|
129
|
-
if (strapi.config.environment !== 'production' || config.playgroundAlways) {
|
|
130
|
-
serverParams.playground = {
|
|
131
|
-
endpoint: `${strapi.config.server.url}${config.endpoint}`,
|
|
132
|
-
shareEnabled: config.shareEnabled,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const server = new ApolloServer(serverParams);
|
|
137
|
-
|
|
138
|
-
const uploadMiddleware = graphqlUploadKoa();
|
|
139
|
-
strapi.app.use((ctx, next) => {
|
|
140
|
-
if (ctx.path === config.endpoint) {
|
|
141
|
-
return uploadMiddleware(ctx, next);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return next();
|
|
145
|
-
});
|
|
146
|
-
server.applyMiddleware({
|
|
147
|
-
app: strapi.app,
|
|
148
|
-
path: config.endpoint,
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
strapi.plugins.graphql.destroy = async () => {
|
|
152
|
-
await server.stop();
|
|
153
|
-
};
|
|
154
|
-
},
|
|
155
|
-
};
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Merges a list of schemas
|
|
160
|
-
* @param {Array<Object>} schemas - The list of schemas to merge
|
|
161
|
-
*/
|
|
162
|
-
const mergeSchemas = schemas => {
|
|
163
|
-
return schemas.reduce((acc, el) => {
|
|
164
|
-
const { definition, query, mutation, type, resolver } = el;
|
|
165
|
-
|
|
166
|
-
return _.merge(acc, {
|
|
167
|
-
definition: `${acc.definition || ''} ${definition || ''}`,
|
|
168
|
-
query: `${acc.query || ''} ${query || ''}`,
|
|
169
|
-
mutation: `${acc.mutation || ''} ${mutation || ''}`,
|
|
170
|
-
type,
|
|
171
|
-
resolver,
|
|
172
|
-
});
|
|
173
|
-
}, {});
|
|
174
|
-
};
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// eslint-disable-next-line node/no-extraneous-require
|
|
4
|
-
const loadUtils = require('@strapi/strapi/lib/load');
|
|
5
|
-
const _ = require('lodash');
|
|
6
|
-
|
|
7
|
-
const loadApisGraphqlConfig = appPath =>
|
|
8
|
-
loadUtils.loadFiles(appPath, 'api/**/config/*.graphql?(.js)');
|
|
9
|
-
|
|
10
|
-
const loadPluginsGraphqlConfig = async installedPlugins => {
|
|
11
|
-
const root = {};
|
|
12
|
-
|
|
13
|
-
for (let pluginName of installedPlugins) {
|
|
14
|
-
const pluginDir = loadUtils.findPackagePath(`@strapi/plugin-${pluginName}`);
|
|
15
|
-
|
|
16
|
-
const result = await loadUtils.loadFiles(pluginDir, 'config/*.graphql?(.js)');
|
|
17
|
-
|
|
18
|
-
_.set(root, ['plugins', pluginName], result);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return root;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const loadLocalPluginsGraphqlConfig = async appPath =>
|
|
25
|
-
loadUtils.loadFiles(appPath, 'plugins/**/config/*.graphql?(.js)');
|
|
26
|
-
|
|
27
|
-
const loadExtensions = async appPath =>
|
|
28
|
-
loadUtils.loadFiles(appPath, 'extensions/**/config/*.graphql?(.js)');
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Loads the graphql config files
|
|
32
|
-
*/
|
|
33
|
-
module.exports = async ({ appPath, installedPlugins }) => {
|
|
34
|
-
const [apis, plugins, localPlugins, extensions] = await Promise.all([
|
|
35
|
-
loadApisGraphqlConfig(appPath),
|
|
36
|
-
loadPluginsGraphqlConfig(installedPlugins),
|
|
37
|
-
loadLocalPluginsGraphqlConfig(appPath),
|
|
38
|
-
loadExtensions(appPath),
|
|
39
|
-
]);
|
|
40
|
-
|
|
41
|
-
return _.merge({}, apis, plugins, extensions, localPlugins);
|
|
42
|
-
};
|