@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
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
mergeSchemas,
|
|
5
|
+
makeExecutableSchema,
|
|
6
|
+
addResolversToSchema,
|
|
7
|
+
} = require('@graphql-tools/schema');
|
|
8
|
+
const { makeSchema } = require('nexus');
|
|
9
|
+
const { pipe, prop, startsWith } = require('lodash/fp');
|
|
10
|
+
|
|
11
|
+
const { wrapResolvers } = require('./wrap-resolvers');
|
|
12
|
+
const {
|
|
13
|
+
registerSingleType,
|
|
14
|
+
registerCollectionType,
|
|
15
|
+
registerComponent,
|
|
16
|
+
registerScalars,
|
|
17
|
+
registerInternals,
|
|
18
|
+
registerPolymorphicContentType,
|
|
19
|
+
contentType: {
|
|
20
|
+
registerEnumsDefinition,
|
|
21
|
+
registerInputsDefinition,
|
|
22
|
+
registerFiltersDefinition,
|
|
23
|
+
registerDynamicZonesDefinition,
|
|
24
|
+
},
|
|
25
|
+
} = require('./register-functions');
|
|
26
|
+
|
|
27
|
+
module.exports = ({ strapi }) => {
|
|
28
|
+
const { service: getGraphQLService } = strapi.plugin('graphql');
|
|
29
|
+
const { config } = strapi.plugin('graphql');
|
|
30
|
+
|
|
31
|
+
const { KINDS, GENERIC_MORPH_TYPENAME } = getGraphQLService('constants');
|
|
32
|
+
|
|
33
|
+
// Type Registry
|
|
34
|
+
let registry;
|
|
35
|
+
// Builders Instances
|
|
36
|
+
let builders;
|
|
37
|
+
|
|
38
|
+
const buildSchema = () => {
|
|
39
|
+
const extensionService = getGraphQLService('extension');
|
|
40
|
+
|
|
41
|
+
const isShadowCRUDEnabled = !!config('shadowCRUD', true);
|
|
42
|
+
|
|
43
|
+
// Create a new empty type registry
|
|
44
|
+
registry = getGraphQLService('type-registry').new();
|
|
45
|
+
|
|
46
|
+
// Reset the builders instances associated to the
|
|
47
|
+
// content-api, and link the new type registry
|
|
48
|
+
builders = getGraphQLService('builders').new('content-api', registry);
|
|
49
|
+
|
|
50
|
+
registerScalars({ registry, strapi });
|
|
51
|
+
registerInternals({ registry, strapi });
|
|
52
|
+
|
|
53
|
+
if (isShadowCRUDEnabled) {
|
|
54
|
+
shadowCRUD();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Generate the extension configuration for the content API
|
|
58
|
+
const extension = extensionService.generate({ typeRegistry: registry });
|
|
59
|
+
|
|
60
|
+
return pipe(
|
|
61
|
+
// Build a collection of schema based on the
|
|
62
|
+
// type registry & the extension configuration
|
|
63
|
+
buildSchemas,
|
|
64
|
+
// Merge every created schema into a single one
|
|
65
|
+
schemas => mergeSchemas({ schemas }),
|
|
66
|
+
// Add the extension's resolvers to the final schema
|
|
67
|
+
schema => addResolversToSchema(schema, extension.resolvers),
|
|
68
|
+
// Wrap resolvers if needed (auth, middlewares, policies...) as configured in the extension
|
|
69
|
+
schema => wrapResolvers({ schema, strapi, extension })
|
|
70
|
+
)({ registry, extension });
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const buildSchemas = ({ registry, extension }) => {
|
|
74
|
+
const { types, plugins, typeDefs = [] } = extension;
|
|
75
|
+
|
|
76
|
+
// Create a new Nexus schema (shadow CRUD) & add it to the schemas collection
|
|
77
|
+
const nexusSchema = makeSchema({
|
|
78
|
+
types: [
|
|
79
|
+
// Add the auto-generated Nexus types (shadow CRUD)
|
|
80
|
+
registry.definitions,
|
|
81
|
+
// Add every Nexus type registered using the extension service
|
|
82
|
+
types,
|
|
83
|
+
],
|
|
84
|
+
|
|
85
|
+
plugins: [
|
|
86
|
+
// Add every plugin registered using the extension service
|
|
87
|
+
...plugins,
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Build schemas based on SDL type definitions (defined in the extension)
|
|
92
|
+
const sdlSchemas = typeDefs.map(sdl => makeExecutableSchema({ typeDefs: sdl }));
|
|
93
|
+
|
|
94
|
+
return [nexusSchema, ...sdlSchemas];
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const shadowCRUD = () => {
|
|
98
|
+
const extensionService = getGraphQLService('extension');
|
|
99
|
+
|
|
100
|
+
// Get every content type & component defined in Strapi
|
|
101
|
+
const contentTypes = [
|
|
102
|
+
...Object.values(strapi.components),
|
|
103
|
+
...Object.values(strapi.contentTypes),
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
// Disable Shadow CRUD for admin content types
|
|
107
|
+
contentTypes
|
|
108
|
+
.map(prop('uid'))
|
|
109
|
+
.filter(startsWith('admin::'))
|
|
110
|
+
.forEach(uid => extensionService.shadowCRUD(uid).disable());
|
|
111
|
+
|
|
112
|
+
const contentTypesWithShadowCRUD = contentTypes.filter(ct =>
|
|
113
|
+
extensionService.shadowCRUD(ct.uid).isEnabled()
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// Generate and register definitions for every content type
|
|
117
|
+
registerAPITypes(contentTypesWithShadowCRUD);
|
|
118
|
+
|
|
119
|
+
// Generate and register polymorphic types' definitions
|
|
120
|
+
registerMorphTypes(contentTypesWithShadowCRUD);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Register needed GraphQL types for every content type
|
|
125
|
+
* @param {object[]} contentTypes
|
|
126
|
+
*/
|
|
127
|
+
const registerAPITypes = contentTypes => {
|
|
128
|
+
for (const contentType of contentTypes) {
|
|
129
|
+
const { kind, modelType } = contentType;
|
|
130
|
+
|
|
131
|
+
const registerOptions = { registry, strapi, builders };
|
|
132
|
+
|
|
133
|
+
// Generate various types associated to the content type
|
|
134
|
+
// (enums, dynamic-zones, filters, inputs...)
|
|
135
|
+
registerEnumsDefinition(contentType, registerOptions);
|
|
136
|
+
registerDynamicZonesDefinition(contentType, registerOptions);
|
|
137
|
+
registerFiltersDefinition(contentType, registerOptions);
|
|
138
|
+
registerInputsDefinition(contentType, registerOptions);
|
|
139
|
+
|
|
140
|
+
// Generate & register component's definition
|
|
141
|
+
if (modelType === 'component') {
|
|
142
|
+
registerComponent(contentType, registerOptions);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Generate & register single type's definition
|
|
146
|
+
else if (kind === 'singleType') {
|
|
147
|
+
registerSingleType(contentType, registerOptions);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Generate & register collection type's definition
|
|
151
|
+
else if (kind === 'collectionType') {
|
|
152
|
+
registerCollectionType(contentType, registerOptions);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const registerMorphTypes = contentTypes => {
|
|
158
|
+
// Create & register a union type that includes every type or component registered
|
|
159
|
+
const genericMorphType = builders.buildGenericMorphDefinition();
|
|
160
|
+
registry.register(GENERIC_MORPH_TYPENAME, genericMorphType, { kind: KINDS.morph });
|
|
161
|
+
|
|
162
|
+
for (const contentType of contentTypes) {
|
|
163
|
+
registerPolymorphicContentType(contentType, { registry, strapi });
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
return { buildSchema };
|
|
168
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { getOr } = require('lodash/fp');
|
|
4
|
+
const { policy: policyUtils } = require('@strapi/utils');
|
|
5
|
+
|
|
6
|
+
const createPoliciesMiddleware = (resolverConfig, { strapi }) => {
|
|
7
|
+
return async (resolve, ...rest) => {
|
|
8
|
+
const resolverPolicies = getOr([], 'policies', resolverConfig);
|
|
9
|
+
|
|
10
|
+
// Transform every policy into a unique format
|
|
11
|
+
const policies = resolverPolicies.map(policy => policyUtils.get(policy));
|
|
12
|
+
|
|
13
|
+
// Create a graphql policy context
|
|
14
|
+
const context = createGraphQLPolicyContext(...rest);
|
|
15
|
+
|
|
16
|
+
// Run policies & throw an error if one of them fails
|
|
17
|
+
for (const policy of policies) {
|
|
18
|
+
const result = await policy({ context, strapi });
|
|
19
|
+
|
|
20
|
+
if (!result) {
|
|
21
|
+
throw new Error('Policies failed');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return resolve(...rest);
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const createGraphQLPolicyContext = (parent, args, context, info) => {
|
|
30
|
+
return policyUtils.createPolicyContext('graphql', {
|
|
31
|
+
get parent() {
|
|
32
|
+
return parent;
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
get args() {
|
|
36
|
+
return args;
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
get context() {
|
|
40
|
+
return context;
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
get info() {
|
|
44
|
+
return info;
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
get state() {
|
|
48
|
+
return this.context.state;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
get http() {
|
|
52
|
+
return this.context.koaContext;
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
module.exports = {
|
|
58
|
+
createPoliciesMiddleware,
|
|
59
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerCollectionType = (contentType, { registry, strapi, builders }) => {
|
|
4
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
5
|
+
|
|
6
|
+
const { naming } = getService('utils');
|
|
7
|
+
const { KINDS } = getService('constants');
|
|
8
|
+
|
|
9
|
+
const extension = getService('extension');
|
|
10
|
+
|
|
11
|
+
// Types name (as string)
|
|
12
|
+
const types = {
|
|
13
|
+
base: naming.getTypeName(contentType),
|
|
14
|
+
entity: naming.getEntityName(contentType),
|
|
15
|
+
response: naming.getEntityResponseName(contentType),
|
|
16
|
+
responseCollection: naming.getEntityResponseCollectionName(contentType),
|
|
17
|
+
relationResponseCollection: naming.getRelationResponseCollectionName(contentType),
|
|
18
|
+
queries: naming.getEntityQueriesTypeName(contentType),
|
|
19
|
+
mutations: naming.getEntityMutationsTypeName(contentType),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const getConfig = kind => ({ kind, contentType });
|
|
23
|
+
|
|
24
|
+
// Type definition
|
|
25
|
+
registry.register(types.base, builders.buildTypeDefinition(contentType), getConfig(KINDS.type));
|
|
26
|
+
|
|
27
|
+
// Higher level entity definition
|
|
28
|
+
registry.register(
|
|
29
|
+
types.entity,
|
|
30
|
+
builders.buildEntityDefinition(contentType),
|
|
31
|
+
getConfig(KINDS.entity)
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Responses definition
|
|
35
|
+
registry.register(
|
|
36
|
+
types.response,
|
|
37
|
+
builders.buildResponseDefinition(contentType),
|
|
38
|
+
getConfig(KINDS.entityResponse)
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
registry.register(
|
|
42
|
+
types.responseCollection,
|
|
43
|
+
builders.buildResponseCollectionDefinition(contentType),
|
|
44
|
+
getConfig(KINDS.entityResponseCollection)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
registry.register(
|
|
48
|
+
types.relationResponseCollection,
|
|
49
|
+
builders.buildRelationResponseCollectionDefinition(contentType),
|
|
50
|
+
getConfig(KINDS.relationResponseCollection)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if (extension.shadowCRUD(contentType.uid).areQueriesEnabled()) {
|
|
54
|
+
// Query extensions
|
|
55
|
+
registry.register(
|
|
56
|
+
types.queries,
|
|
57
|
+
builders.buildCollectionTypeQueries(contentType),
|
|
58
|
+
getConfig(KINDS.query)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (extension.shadowCRUD(contentType.uid).areMutationsEnabled()) {
|
|
63
|
+
// Mutation extensions
|
|
64
|
+
registry.register(
|
|
65
|
+
types.mutations,
|
|
66
|
+
builders.buildCollectionTypeMutations(contentType),
|
|
67
|
+
getConfig(KINDS.mutation)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
module.exports = { registerCollectionType };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerComponent = (contentType, { registry, strapi, builders }) => {
|
|
4
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
5
|
+
|
|
6
|
+
const { getComponentName } = getService('utils').naming;
|
|
7
|
+
const { KINDS } = getService('constants');
|
|
8
|
+
|
|
9
|
+
const name = getComponentName(contentType);
|
|
10
|
+
const definition = builders.buildTypeDefinition(contentType);
|
|
11
|
+
|
|
12
|
+
registry.register(name, definition, { kind: KINDS.component, contentType });
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
module.exports = { registerComponent };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerDynamicZonesDefinition = (contentType, { registry, strapi, builders }) => {
|
|
4
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
naming,
|
|
8
|
+
attributes: { isDynamicZone },
|
|
9
|
+
} = getService('utils');
|
|
10
|
+
const { KINDS } = getService('constants');
|
|
11
|
+
|
|
12
|
+
const { attributes } = contentType;
|
|
13
|
+
|
|
14
|
+
const dynamicZoneAttributes = Object.keys(attributes).filter(attributeName =>
|
|
15
|
+
isDynamicZone(attributes[attributeName])
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
for (const attributeName of dynamicZoneAttributes) {
|
|
19
|
+
const attribute = attributes[attributeName];
|
|
20
|
+
const dzName = naming.getDynamicZoneName(contentType, attributeName);
|
|
21
|
+
const dzInputName = naming.getDynamicZoneInputName(contentType, attributeName);
|
|
22
|
+
|
|
23
|
+
const [type, input] = builders.buildDynamicZoneDefinition(attribute, dzName, dzInputName);
|
|
24
|
+
|
|
25
|
+
const baseConfig = {
|
|
26
|
+
contentType,
|
|
27
|
+
attributeName,
|
|
28
|
+
attribute,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
registry.register(dzName, type, { kind: KINDS.dynamicZone, ...baseConfig });
|
|
32
|
+
registry.register(dzInputName, input, { kind: KINDS.input, ...baseConfig });
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
module.exports = { registerDynamicZonesDefinition };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerEnumsDefinition = (contentType, { registry, strapi, builders }) => {
|
|
4
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
naming,
|
|
8
|
+
attributes: { isEnumeration },
|
|
9
|
+
} = getService('utils');
|
|
10
|
+
const { KINDS } = getService('constants');
|
|
11
|
+
|
|
12
|
+
const { attributes } = contentType;
|
|
13
|
+
|
|
14
|
+
const enumAttributes = Object.keys(attributes).filter(attributeName =>
|
|
15
|
+
isEnumeration(attributes[attributeName])
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
for (const attributeName of enumAttributes) {
|
|
19
|
+
const attribute = attributes[attributeName];
|
|
20
|
+
|
|
21
|
+
const enumName = naming.getEnumName(contentType, attributeName);
|
|
22
|
+
const enumDefinition = builders.buildEnumTypeDefinition(attribute, enumName);
|
|
23
|
+
|
|
24
|
+
registry.register(enumName, enumDefinition, {
|
|
25
|
+
kind: KINDS.enum,
|
|
26
|
+
contentType,
|
|
27
|
+
attributeName,
|
|
28
|
+
attribute,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
module.exports = { registerEnumsDefinition };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerFiltersDefinition = (contentType, { registry, strapi, builders }) => {
|
|
4
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
5
|
+
|
|
6
|
+
const { getFiltersInputTypeName } = getService('utils').naming;
|
|
7
|
+
const { KINDS } = getService('constants');
|
|
8
|
+
|
|
9
|
+
const type = getFiltersInputTypeName(contentType);
|
|
10
|
+
const definition = builders.buildContentTypeFilters(contentType);
|
|
11
|
+
|
|
12
|
+
registry.register(type, definition, { kind: KINDS.filtersInput, contentType });
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
module.exports = { registerFiltersDefinition };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { registerDynamicZonesDefinition } = require('./dynamic-zones');
|
|
4
|
+
const { registerEnumsDefinition } = require('./enums');
|
|
5
|
+
const { registerInputsDefinition } = require('./inputs');
|
|
6
|
+
const { registerFiltersDefinition } = require('./filters');
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
registerDynamicZonesDefinition,
|
|
10
|
+
registerFiltersDefinition,
|
|
11
|
+
registerInputsDefinition,
|
|
12
|
+
registerEnumsDefinition,
|
|
13
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerInputsDefinition = (contentType, { registry, strapi, builders }) => {
|
|
4
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
5
|
+
|
|
6
|
+
const { getComponentInputName, getContentTypeInputName } = getService('utils').naming;
|
|
7
|
+
const { KINDS } = getService('constants');
|
|
8
|
+
|
|
9
|
+
const { modelType } = contentType;
|
|
10
|
+
|
|
11
|
+
const type = (modelType === 'component' ? getComponentInputName : getContentTypeInputName).call(
|
|
12
|
+
null,
|
|
13
|
+
contentType
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const definition = builders.buildInputType(contentType);
|
|
17
|
+
|
|
18
|
+
registry.register(type, definition, { kind: KINDS.input, contentType });
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
module.exports = { registerInputsDefinition };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { registerCollectionType } = require('./collection-type');
|
|
4
|
+
const { registerSingleType } = require('./single-type');
|
|
5
|
+
const { registerComponent } = require('./component');
|
|
6
|
+
const { registerPolymorphicContentType } = require('./polymorphic');
|
|
7
|
+
|
|
8
|
+
const { registerScalars } = require('./scalars');
|
|
9
|
+
const { registerInternals } = require('./internals');
|
|
10
|
+
|
|
11
|
+
const contentType = require('./content-type');
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
registerCollectionType,
|
|
15
|
+
registerSingleType,
|
|
16
|
+
registerComponent,
|
|
17
|
+
registerPolymorphicContentType,
|
|
18
|
+
registerInternals,
|
|
19
|
+
registerScalars,
|
|
20
|
+
|
|
21
|
+
contentType,
|
|
22
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerInternals = ({ registry, strapi }) => {
|
|
4
|
+
const { buildInternalTypes } = strapi.plugin('graphql').service('internals');
|
|
5
|
+
|
|
6
|
+
const internalTypes = buildInternalTypes({ strapi });
|
|
7
|
+
|
|
8
|
+
for (const [kind, definitions] of Object.entries(internalTypes)) {
|
|
9
|
+
registry.registerMany(Object.entries(definitions), { kind });
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
module.exports = { registerInternals };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { unionType } = require('nexus');
|
|
4
|
+
|
|
5
|
+
const registerPolymorphicContentType = (contentType, { registry, strapi }) => {
|
|
6
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
7
|
+
|
|
8
|
+
const {
|
|
9
|
+
naming,
|
|
10
|
+
attributes: { isMorphRelation },
|
|
11
|
+
} = getService('utils');
|
|
12
|
+
const { KINDS } = getService('constants');
|
|
13
|
+
|
|
14
|
+
const { attributes = {} } = contentType;
|
|
15
|
+
|
|
16
|
+
// Isolate its polymorphic attributes
|
|
17
|
+
const morphAttributes = Object.entries(attributes).filter(([, attribute]) =>
|
|
18
|
+
isMorphRelation(attribute)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// For each one of those polymorphic attribute
|
|
22
|
+
for (const [attributeName, attribute] of morphAttributes) {
|
|
23
|
+
const name = naming.getMorphRelationTypeName(contentType, attributeName);
|
|
24
|
+
const { target } = attribute;
|
|
25
|
+
|
|
26
|
+
// Ignore those whose target is not an array
|
|
27
|
+
if (!Array.isArray(target)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Transform target UIDs into types names
|
|
32
|
+
const members = target
|
|
33
|
+
// Get content types definitions
|
|
34
|
+
.map(uid => strapi.getModel(uid))
|
|
35
|
+
// Resolve types names
|
|
36
|
+
.map(contentType => naming.getTypeName(contentType));
|
|
37
|
+
|
|
38
|
+
// Register the new polymorphic union type
|
|
39
|
+
registry.register(
|
|
40
|
+
name,
|
|
41
|
+
|
|
42
|
+
unionType({
|
|
43
|
+
name,
|
|
44
|
+
|
|
45
|
+
resolveType(obj) {
|
|
46
|
+
const contentType = strapi.getModel(obj.__type);
|
|
47
|
+
|
|
48
|
+
if (!contentType) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (contentType.modelType === 'component') {
|
|
53
|
+
return naming.getComponentName(contentType);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return naming.getTypeName(contentType);
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
definition(t) {
|
|
60
|
+
t.members(...members);
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
|
|
64
|
+
{ kind: KINDS.morph, contentType, attributeName }
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
module.exports = { registerPolymorphicContentType };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerScalars = ({ registry, strapi }) => {
|
|
4
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
5
|
+
|
|
6
|
+
const { scalars } = getService('internals');
|
|
7
|
+
const { KINDS } = getService('constants');
|
|
8
|
+
|
|
9
|
+
Object.entries(scalars).forEach(([name, definition]) => {
|
|
10
|
+
registry.register(name, definition, { kind: KINDS.scalar });
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = { registerScalars };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const registerSingleType = (contentType, { registry, strapi, builders }) => {
|
|
4
|
+
const { service: getService } = strapi.plugin('graphql');
|
|
5
|
+
|
|
6
|
+
const { naming } = getService('utils');
|
|
7
|
+
const { KINDS } = getService('constants');
|
|
8
|
+
|
|
9
|
+
const extension = getService('extension');
|
|
10
|
+
|
|
11
|
+
const types = {
|
|
12
|
+
base: naming.getTypeName(contentType),
|
|
13
|
+
entity: naming.getEntityName(contentType),
|
|
14
|
+
response: naming.getEntityResponseName(contentType),
|
|
15
|
+
responseCollection: naming.getEntityResponseCollectionName(contentType),
|
|
16
|
+
relationResponseCollection: naming.getRelationResponseCollectionName(contentType),
|
|
17
|
+
queries: naming.getEntityQueriesTypeName(contentType),
|
|
18
|
+
mutations: naming.getEntityMutationsTypeName(contentType),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const getConfig = kind => ({ kind, contentType });
|
|
22
|
+
|
|
23
|
+
// Single type's definition
|
|
24
|
+
registry.register(types.base, builders.buildTypeDefinition(contentType), getConfig(KINDS.type));
|
|
25
|
+
|
|
26
|
+
// Higher level entity definition
|
|
27
|
+
registry.register(
|
|
28
|
+
types.entity,
|
|
29
|
+
builders.buildEntityDefinition(contentType),
|
|
30
|
+
getConfig(KINDS.entity)
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// Responses definition
|
|
34
|
+
registry.register(
|
|
35
|
+
types.response,
|
|
36
|
+
builders.buildResponseDefinition(contentType),
|
|
37
|
+
getConfig(KINDS.entityResponse)
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Response collection definition
|
|
41
|
+
registry.register(
|
|
42
|
+
types.responseCollection,
|
|
43
|
+
builders.buildResponseCollectionDefinition(contentType),
|
|
44
|
+
getConfig(KINDS.entityResponseCollection)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
registry.register(
|
|
48
|
+
types.relationResponseCollection,
|
|
49
|
+
builders.buildRelationResponseCollectionDefinition(contentType),
|
|
50
|
+
getConfig(KINDS.relationResponseCollection)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if (extension.shadowCRUD(contentType.uid).areQueriesEnabled()) {
|
|
54
|
+
// Queries
|
|
55
|
+
registry.register(
|
|
56
|
+
types.queries,
|
|
57
|
+
builders.buildSingleTypeQueries(contentType),
|
|
58
|
+
getConfig(KINDS.query)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (extension.shadowCRUD(contentType.uid).areMutationsEnabled()) {
|
|
63
|
+
// Mutations
|
|
64
|
+
registry.register(
|
|
65
|
+
types.mutations,
|
|
66
|
+
builders.buildSingleTypeMutations(contentType),
|
|
67
|
+
getConfig(KINDS.mutation)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
module.exports = { registerSingleType };
|