@strapi/plugin-graphql 4.0.0-next.7 → 4.0.1

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 (122) hide show
  1. package/README.md +1 -1
  2. package/admin/src/index.js +0 -8
  3. package/package.json +43 -35
  4. package/server/bootstrap.js +148 -0
  5. package/server/config/default-config.js +13 -0
  6. package/server/config/index.js +7 -0
  7. package/server/format-graphql-error.js +50 -0
  8. package/server/services/builders/dynamic-zones.js +97 -0
  9. package/server/services/builders/entity-meta.js +7 -0
  10. package/server/services/builders/entity.js +43 -0
  11. package/server/services/builders/enums.js +24 -0
  12. package/server/services/builders/filters/content-type.js +93 -0
  13. package/server/services/builders/filters/index.js +7 -0
  14. package/server/services/builders/filters/operators/and.js +15 -0
  15. package/server/services/builders/filters/operators/between.js +15 -0
  16. package/server/services/builders/filters/operators/contains.js +13 -0
  17. package/server/services/builders/filters/operators/containsi.js +13 -0
  18. package/server/services/builders/filters/operators/ends-with.js +13 -0
  19. package/server/services/builders/filters/operators/eq.js +23 -0
  20. package/server/services/builders/filters/operators/gt.js +13 -0
  21. package/server/services/builders/filters/operators/gte.js +13 -0
  22. package/server/services/builders/filters/operators/in.js +15 -0
  23. package/server/services/builders/filters/operators/index.js +38 -0
  24. package/server/services/builders/filters/operators/lt.js +13 -0
  25. package/server/services/builders/filters/operators/lte.js +13 -0
  26. package/server/services/builders/filters/operators/ne.js +13 -0
  27. package/server/services/builders/filters/operators/not-contains.js +13 -0
  28. package/server/services/builders/filters/operators/not-containsi.js +13 -0
  29. package/server/services/builders/filters/operators/not-in.js +15 -0
  30. package/server/services/builders/filters/operators/not-null.js +13 -0
  31. package/server/services/builders/filters/operators/not.js +19 -0
  32. package/server/services/builders/filters/operators/null.js +13 -0
  33. package/server/services/builders/filters/operators/or.js +15 -0
  34. package/server/services/builders/filters/operators/starts-with.js +13 -0
  35. package/server/services/builders/generic-morph.js +41 -0
  36. package/server/services/builders/index.js +92 -0
  37. package/server/services/builders/input.js +121 -0
  38. package/server/services/builders/mutations/collection-type.js +191 -0
  39. package/server/services/builders/mutations/index.js +9 -0
  40. package/server/services/builders/mutations/single-type.js +141 -0
  41. package/server/services/builders/queries/collection-type.js +120 -0
  42. package/server/services/builders/queries/index.js +9 -0
  43. package/server/services/builders/queries/single-type.js +70 -0
  44. package/server/services/builders/relation-response-collection.js +35 -0
  45. package/server/services/builders/resolvers/association.js +85 -0
  46. package/server/services/builders/resolvers/component.js +18 -0
  47. package/server/services/builders/resolvers/dynamic-zone.js +9 -0
  48. package/server/services/builders/resolvers/index.js +18 -0
  49. package/server/services/builders/resolvers/mutation.js +33 -0
  50. package/server/services/builders/resolvers/query.js +19 -0
  51. package/server/services/builders/response-collection.js +43 -0
  52. package/server/services/builders/response.js +32 -0
  53. package/server/services/builders/type.js +364 -0
  54. package/server/services/builders/utils.js +134 -0
  55. package/server/services/constants.js +149 -0
  56. package/server/services/content-api/index.js +179 -0
  57. package/server/services/content-api/policy.js +60 -0
  58. package/server/services/content-api/register-functions/collection-type.js +72 -0
  59. package/server/services/content-api/register-functions/component.js +15 -0
  60. package/server/services/content-api/register-functions/content-type/dynamic-zones.js +36 -0
  61. package/server/services/content-api/register-functions/content-type/enums.js +33 -0
  62. package/server/services/content-api/register-functions/content-type/filters.js +15 -0
  63. package/server/services/content-api/register-functions/content-type/index.js +13 -0
  64. package/server/services/content-api/register-functions/content-type/inputs.js +21 -0
  65. package/server/services/content-api/register-functions/index.js +22 -0
  66. package/server/services/content-api/register-functions/internals.js +13 -0
  67. package/server/services/content-api/register-functions/polymorphic.js +69 -0
  68. package/server/services/content-api/register-functions/scalars.js +14 -0
  69. package/server/services/content-api/register-functions/single-type.js +72 -0
  70. package/server/services/content-api/wrap-resolvers.js +144 -0
  71. package/server/services/extension/extension.js +95 -0
  72. package/server/services/extension/index.js +5 -0
  73. package/server/services/extension/shadow-crud-manager.js +159 -0
  74. package/server/services/format/index.js +7 -0
  75. package/server/services/format/return-types.js +27 -0
  76. package/server/services/index.js +21 -0
  77. package/server/services/internals/args/index.js +11 -0
  78. package/server/services/internals/args/pagination.js +19 -0
  79. package/server/services/internals/args/publication-state.js +12 -0
  80. package/server/services/internals/args/sort.js +10 -0
  81. package/server/services/internals/helpers/get-enabled-scalars.js +15 -0
  82. package/server/services/internals/helpers/index.js +7 -0
  83. package/server/services/internals/index.js +13 -0
  84. package/server/services/internals/scalars/index.js +18 -0
  85. package/server/services/internals/scalars/time.js +36 -0
  86. package/server/services/internals/types/error.js +34 -0
  87. package/server/services/internals/types/filters.js +39 -0
  88. package/server/services/internals/types/index.js +29 -0
  89. package/server/services/internals/types/pagination.js +24 -0
  90. package/server/services/internals/types/publication-state.js +24 -0
  91. package/server/services/internals/types/response-collection-meta.js +39 -0
  92. package/server/services/type-registry.js +104 -0
  93. package/server/services/utils/attributes.js +84 -0
  94. package/server/services/utils/index.js +11 -0
  95. package/server/services/utils/mappers/entity-to-response-entity.js +12 -0
  96. package/server/services/utils/mappers/graphql-filters-to-strapi-query.js +109 -0
  97. package/server/services/utils/mappers/graphql-scalar-to-operators.js +17 -0
  98. package/server/services/utils/mappers/index.js +13 -0
  99. package/server/services/utils/mappers/strapi-scalar-to-graphql-scalar.js +25 -0
  100. package/server/services/utils/naming.js +287 -0
  101. package/strapi-admin.js +3 -0
  102. package/strapi-server.js +7 -9
  103. package/admin/src/assets/images/logo.svg +0 -38
  104. package/config/routes.json +0 -3
  105. package/config/schema.graphql +0 -1
  106. package/config/settings.json +0 -12
  107. package/controllers/GraphQL.js +0 -9
  108. package/hooks/graphql/defaults.json +0 -5
  109. package/hooks/graphql/index.js +0 -174
  110. package/hooks/graphql/load-config.js +0 -42
  111. package/services/build-aggregation.js +0 -565
  112. package/services/data-loaders.js +0 -55
  113. package/services/naming.js +0 -15
  114. package/services/resolvers-builder.js +0 -204
  115. package/services/schema-definitions.js +0 -131
  116. package/services/schema-generator.js +0 -178
  117. package/services/shadow-crud.js +0 -612
  118. package/services/type-builder.js +0 -311
  119. package/services/utils.js +0 -200
  120. package/types/dynamiczoneScalar.js +0 -40
  121. package/types/publication-state.js +0 -16
  122. package/types/time.js +0 -26
@@ -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 };
@@ -0,0 +1,144 @@
1
+ 'use strict';
2
+
3
+ const { get, getOr, isFunction, first, isNil } = require('lodash/fp');
4
+
5
+ const { GraphQLObjectType } = require('graphql');
6
+ const { ForbiddenError } = require('@strapi/utils').errors;
7
+ const { createPoliciesMiddleware } = require('./policy');
8
+
9
+ const introspectionQueries = [
10
+ '__Schema',
11
+ '__Type',
12
+ '__Field',
13
+ '__InputValue',
14
+ '__EnumValue',
15
+ '__Directive',
16
+ ];
17
+
18
+ /**
19
+ * Wrap the schema's resolvers if they've been
20
+ * customized using the GraphQL extension service
21
+ * @param {object} options
22
+ * @param {GraphQLSchema} options.schema
23
+ * @param {object} options.strapi
24
+ * @param {object} options.extension
25
+ * @return {GraphQLSchema}
26
+ */
27
+ const wrapResolvers = ({ schema, strapi, extension = {} }) => {
28
+ // Get all the registered resolvers configuration
29
+ const { resolversConfig = {} } = extension;
30
+
31
+ // Fields filters
32
+ const isValidFieldName = ([field]) => !field.startsWith('__');
33
+
34
+ const typeMap = schema.getTypeMap();
35
+
36
+ Object.entries(typeMap).forEach(([type, definition]) => {
37
+ const isGraphQLObjectType = definition instanceof GraphQLObjectType;
38
+ const isIgnoredType = introspectionQueries.includes(type);
39
+
40
+ if (!isGraphQLObjectType || isIgnoredType) {
41
+ return;
42
+ }
43
+
44
+ const fields = definition.getFields();
45
+ const fieldsToProcess = Object.entries(fields).filter(isValidFieldName);
46
+
47
+ for (const [fieldName, fieldDefinition] of fieldsToProcess) {
48
+ const defaultResolver = get(fieldName);
49
+
50
+ const path = `${type}.${fieldName}`;
51
+ const resolverConfig = getOr({}, path, resolversConfig);
52
+
53
+ const { resolve: baseResolver = defaultResolver } = fieldDefinition;
54
+
55
+ // Parse & initialize the middlewares
56
+ const middlewares = parseMiddlewares(resolverConfig, strapi);
57
+
58
+ // Generate the policy middleware
59
+ const policyMiddleware = createPoliciesMiddleware(resolverConfig, { strapi });
60
+
61
+ // Add the policyMiddleware at the end of the middlewares collection
62
+ middlewares.push(policyMiddleware);
63
+
64
+ // Bind every middleware to the next one
65
+ const boundMiddlewares = middlewares.map((middleware, index, collection) => {
66
+ return (...args) =>
67
+ middleware(
68
+ // Make sure the last middleware in the list calls the baseResolver
69
+ index >= collection.length - 1 ? baseResolver : boundMiddlewares[index + 1],
70
+ ...args
71
+ );
72
+ });
73
+
74
+ /**
75
+ * GraphQL authorization flow
76
+ * @param {object} context
77
+ * @return {Promise<void>}
78
+ */
79
+ const authorize = async ({ context }) => {
80
+ const authConfig = get('auth', resolverConfig);
81
+ const authContext = get('state.auth', context);
82
+
83
+ const isValidType = ['Mutation', 'Query', 'Subscription'].includes(type);
84
+ const hasConfig = !isNil(authConfig);
85
+
86
+ const isAuthDisabled = authConfig === false;
87
+
88
+ if ((isValidType || hasConfig) && !isAuthDisabled) {
89
+ try {
90
+ await strapi.auth.verify(authContext, authConfig);
91
+ } catch (error) {
92
+ throw new ForbiddenError();
93
+ }
94
+ }
95
+ };
96
+
97
+ /**
98
+ * Base resolver wrapper that handles authorization, middlewares & policies
99
+ * @param {object} parent
100
+ * @param {object} args
101
+ * @param {object} context
102
+ * @param {object} info
103
+ * @return {Promise<any>}
104
+ */
105
+ fieldDefinition.resolve = async (parent, args, context, info) => {
106
+ await authorize({ context });
107
+
108
+ // Execute middlewares (including the policy middleware which will always be included)
109
+ return first(boundMiddlewares).call(null, parent, args, context, info);
110
+ };
111
+ }
112
+ });
113
+
114
+ return schema;
115
+ };
116
+
117
+ /**
118
+ * Get & parse middlewares definitions from the resolver's config
119
+ * @param {object} resolverConfig
120
+ * @param {object} strapi
121
+ * @return {function[]}
122
+ */
123
+ const parseMiddlewares = (resolverConfig, strapi) => {
124
+ const resolverMiddlewares = getOr([], 'middlewares', resolverConfig);
125
+
126
+ // TODO: [v4] to factorize with compose endpoints (routes)
127
+ return resolverMiddlewares.map(middleware => {
128
+ if (isFunction(middleware)) {
129
+ return middleware;
130
+ }
131
+
132
+ if (typeof middleware === 'string') {
133
+ return strapi.middleware(middleware);
134
+ }
135
+
136
+ if (typeof middleware === 'object') {
137
+ const { name, options = {} } = middleware;
138
+
139
+ return strapi.middleware(name)(options);
140
+ }
141
+ });
142
+ };
143
+
144
+ module.exports = { wrapResolvers };
@@ -0,0 +1,95 @@
1
+ 'use strict';
2
+
3
+ const nexus = require('nexus');
4
+ const { merge } = require('lodash/fp');
5
+
6
+ const createShadowCRUDManager = require('./shadow-crud-manager');
7
+
8
+ /**
9
+ * @typedef StrapiGraphQLExtensionConfiguration
10
+ * @property {NexusGen[]} types - A collection of Nexus types
11
+ * @property {string} typeDefs - Type definitions (SDL format)
12
+ * @property {object} resolvers - A resolver map
13
+ * @property {object} resolversConfig - An object that bind a configuration to a resolver based on an absolute path (the key)
14
+ * @property {NexusPlugin[]} plugins - A collection of Nexus plugins
15
+ */
16
+
17
+ /**
18
+ * @typedef {function({ strapi: object, nexus: object, typeRegistry: object }): StrapiGraphQLExtensionConfiguration} StrapiGraphQLExtensionConfigurationFactory
19
+ */
20
+
21
+ const getDefaultState = () => ({
22
+ types: [],
23
+ typeDefs: [],
24
+ resolvers: {},
25
+ resolversConfig: {},
26
+ plugins: [],
27
+ });
28
+
29
+ const createExtension = ({ strapi } = {}) => {
30
+ const configs = [];
31
+
32
+ return {
33
+ shadowCRUD: createShadowCRUDManager({ strapi }),
34
+
35
+ /**
36
+ * Register a new extension configuration
37
+ * @param {StrapiGraphQLExtensionConfiguration | StrapiGraphQLExtensionConfigurationFactory} configuration
38
+ * @return {this}
39
+ */
40
+ use(configuration) {
41
+ configs.push(configuration);
42
+
43
+ return this;
44
+ },
45
+
46
+ /**
47
+ * Convert the registered configuration into a single extension object & return it
48
+ * @param {object} options
49
+ * @param {object} options.typeRegistry
50
+ * @return {object}
51
+ */
52
+ generate({ typeRegistry }) {
53
+ const resolveConfig = config => {
54
+ return typeof config === 'function' ? config({ strapi, nexus, typeRegistry }) : config;
55
+ };
56
+
57
+ // Evaluate & merge every registered configuration object, then return the result
58
+ return configs.reduce((acc, configuration) => {
59
+ const { types, typeDefs, resolvers, resolversConfig, plugins } = resolveConfig(
60
+ configuration
61
+ );
62
+
63
+ // Register type definitions
64
+ if (typeof typeDefs === 'string') {
65
+ acc.typeDefs.push(typeDefs);
66
+ }
67
+
68
+ // Register nexus types
69
+ if (Array.isArray(types)) {
70
+ acc.types.push(...types);
71
+ }
72
+
73
+ // Register nexus plugins
74
+ if (Array.isArray(plugins)) {
75
+ acc.plugins.push(...plugins);
76
+ }
77
+
78
+ // Register resolvers
79
+ if (typeof resolvers === 'object') {
80
+ acc.resolvers = merge(acc.resolvers, resolvers);
81
+ }
82
+
83
+ // Register resolvers configuration
84
+ if (typeof resolversConfig === 'object') {
85
+ // TODO: smarter merge for auth, middlewares & policies
86
+ acc.resolversConfig = merge(resolversConfig, acc.resolversConfig);
87
+ }
88
+
89
+ return acc;
90
+ }, getDefaultState());
91
+ },
92
+ };
93
+ };
94
+
95
+ module.exports = createExtension;
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ const createExtension = require('./extension');
4
+
5
+ module.exports = createExtension;
@@ -0,0 +1,159 @@
1
+ 'use strict';
2
+
3
+ const getDefaultContentTypeConfig = () => ({
4
+ enabled: true,
5
+
6
+ mutations: true,
7
+ queries: true,
8
+
9
+ disabledActions: [],
10
+ fields: new Map(),
11
+ });
12
+
13
+ const getDefaultFieldConfig = () => ({
14
+ enabled: true,
15
+
16
+ input: true,
17
+ output: true,
18
+
19
+ filters: true,
20
+ });
21
+
22
+ const ALL_ACTIONS = '*';
23
+
24
+ module.exports = () => {
25
+ const configs = new Map();
26
+
27
+ return uid => {
28
+ if (!configs.has(uid)) {
29
+ configs.set(uid, getDefaultContentTypeConfig());
30
+ }
31
+
32
+ return {
33
+ isEnabled() {
34
+ return configs.get(uid).enabled;
35
+ },
36
+
37
+ isDisabled() {
38
+ return !this.isEnabled();
39
+ },
40
+
41
+ areQueriesEnabled() {
42
+ return configs.get(uid).queries;
43
+ },
44
+
45
+ areQueriesDisabled() {
46
+ return !this.areQueriesEnabled();
47
+ },
48
+
49
+ areMutationsEnabled() {
50
+ return configs.get(uid).mutations;
51
+ },
52
+
53
+ areMutationsDisabled() {
54
+ return !this.areMutationsEnabled();
55
+ },
56
+
57
+ isActionEnabled(action) {
58
+ const matchingActions = [action, ALL_ACTIONS];
59
+
60
+ return configs.get(uid).disabledActions.every(action => !matchingActions.includes(action));
61
+ },
62
+
63
+ isActionDisabled(action) {
64
+ return !this.isActionEnabled(action);
65
+ },
66
+
67
+ disable() {
68
+ configs.get(uid).enabled = false;
69
+
70
+ return this;
71
+ },
72
+
73
+ disableQueries() {
74
+ configs.get(uid).queries = false;
75
+
76
+ return this;
77
+ },
78
+
79
+ disableMutations() {
80
+ configs.get(uid).mutations = false;
81
+
82
+ return this;
83
+ },
84
+
85
+ disableAction(action) {
86
+ const config = configs.get(uid);
87
+
88
+ if (!config.disabledActions.includes(action)) {
89
+ config.disabledActions.push(action);
90
+ }
91
+
92
+ return this;
93
+ },
94
+
95
+ disableActions(actions = []) {
96
+ actions.forEach(action => this.disableAction(action));
97
+
98
+ return this;
99
+ },
100
+
101
+ field(fieldName) {
102
+ const { fields } = configs.get(uid);
103
+
104
+ if (!fields.has(fieldName)) {
105
+ fields.set(fieldName, getDefaultFieldConfig());
106
+ }
107
+
108
+ return {
109
+ isEnabled() {
110
+ return fields.get(fieldName).enabled;
111
+ },
112
+
113
+ hasInputEnabled() {
114
+ return fields.get(fieldName).input;
115
+ },
116
+
117
+ hasOutputEnabled() {
118
+ return fields.get(fieldName).output;
119
+ },
120
+
121
+ hasFiltersEnabeld() {
122
+ return fields.get(fieldName).filters;
123
+ },
124
+
125
+ disable() {
126
+ fields.set(fieldName, {
127
+ enabled: false,
128
+
129
+ output: false,
130
+ input: false,
131
+
132
+ filters: false,
133
+ });
134
+
135
+ return this;
136
+ },
137
+
138
+ disableOutput() {
139
+ fields.get(fieldName).output = false;
140
+
141
+ return this;
142
+ },
143
+
144
+ disableInput() {
145
+ fields.get(fieldName).input = false;
146
+
147
+ return this;
148
+ },
149
+
150
+ disableFilters() {
151
+ fields.get(fieldName).filters = false;
152
+
153
+ return this;
154
+ },
155
+ };
156
+ },
157
+ };
158
+ };
159
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ const returnTypes = require('./return-types');
4
+
5
+ module.exports = context => ({
6
+ returnTypes: returnTypes(context),
7
+ });
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ module.exports = () => ({
4
+ /**
5
+ * @param {object} value
6
+ * @param {object} info
7
+ * @param {object} info.args
8
+ * @param {string} info.resourceUID
9
+ */
10
+ toEntityResponse(value, info = {}) {
11
+ const { args = {}, resourceUID } = info;
12
+
13
+ return { value, info: { args, resourceUID } };
14
+ },
15
+
16
+ /**
17
+ * @param {object[]} nodes
18
+ * @param {object} info
19
+ * @param {object} info.args
20
+ * @param {string} info.resourceUID
21
+ */
22
+ toEntityResponseCollection(nodes, info = {}) {
23
+ const { args = {}, resourceUID } = info;
24
+
25
+ return { nodes, info: { args, resourceUID } };
26
+ },
27
+ });
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ const contentAPI = require('./content-api');
4
+ const typeRegistry = require('./type-registry');
5
+ const utils = require('./utils');
6
+ const constants = require('./constants');
7
+ const internals = require('./internals');
8
+ const builders = require('./builders');
9
+ const extension = require('./extension');
10
+ const format = require('./format');
11
+
12
+ module.exports = {
13
+ builders,
14
+ 'content-api': contentAPI,
15
+ constants,
16
+ extension,
17
+ format,
18
+ internals,
19
+ 'type-registry': typeRegistry,
20
+ utils,
21
+ };
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ const SortArg = require('./sort');
4
+ const publicationState = require('./publication-state');
5
+ const PaginationArg = require('./pagination');
6
+
7
+ module.exports = context => ({
8
+ SortArg,
9
+ PaginationArg,
10
+ PublicationStateArg: publicationState(context),
11
+ });
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ const { arg, inputObjectType } = require('nexus');
4
+
5
+ const PaginationInputType = inputObjectType({
6
+ name: 'PaginationArg',
7
+
8
+ definition(t) {
9
+ t.int('page');
10
+ t.int('pageSize');
11
+ t.int('start');
12
+ t.int('limit');
13
+ },
14
+ });
15
+
16
+ module.exports = arg({
17
+ type: PaginationInputType,
18
+ default: {},
19
+ });
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const { arg } = require('nexus');
4
+
5
+ module.exports = ({ strapi }) => {
6
+ const { PUBLICATION_STATE_TYPE_NAME } = strapi.plugin('graphql').service('constants');
7
+
8
+ return arg({
9
+ type: PUBLICATION_STATE_TYPE_NAME,
10
+ default: 'live',
11
+ });
12
+ };
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ const { arg, list } = require('nexus');
4
+
5
+ const SortArg = arg({
6
+ type: list('String'),
7
+ default: [],
8
+ });
9
+
10
+ module.exports = SortArg;
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ const { first } = require('lodash/fp');
4
+
5
+ module.exports = ({ strapi }) => () => {
6
+ const { GRAPHQL_SCALAR_OPERATORS } = strapi.plugin('graphql').service('constants');
7
+
8
+ return (
9
+ Object.entries(GRAPHQL_SCALAR_OPERATORS)
10
+ // To be valid, a GraphQL scalar must have at least one operator enabled
11
+ .filter(([, value]) => value.length > 0)
12
+ // Only keep the key (the scalar name)
13
+ .map(first)
14
+ );
15
+ };