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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/admin/src/translations/zh-Hans.json +4 -0
  2. package/package.json +17 -15
  3. package/server/bootstrap.js +124 -0
  4. package/server/services/builders/dynamic-zones.js +96 -0
  5. package/server/services/builders/entity-meta.js +7 -0
  6. package/server/services/builders/entity.js +43 -0
  7. package/server/services/builders/enums.js +24 -0
  8. package/server/services/builders/filters/content-type.js +84 -0
  9. package/server/services/builders/filters/index.js +7 -0
  10. package/server/services/builders/filters/operators/and.js +15 -0
  11. package/server/services/builders/filters/operators/between.js +15 -0
  12. package/server/services/builders/filters/operators/contains.js +13 -0
  13. package/server/services/builders/filters/operators/containsi.js +13 -0
  14. package/server/services/builders/filters/operators/ends-with.js +13 -0
  15. package/server/services/builders/filters/operators/eq.js +19 -0
  16. package/server/services/builders/filters/operators/gt.js +13 -0
  17. package/server/services/builders/filters/operators/gte.js +13 -0
  18. package/server/services/builders/filters/operators/in.js +15 -0
  19. package/server/services/builders/filters/operators/index.js +38 -0
  20. package/server/services/builders/filters/operators/lt.js +13 -0
  21. package/server/services/builders/filters/operators/lte.js +13 -0
  22. package/server/services/builders/filters/operators/ne.js +13 -0
  23. package/server/services/builders/filters/operators/not-contains.js +13 -0
  24. package/server/services/builders/filters/operators/not-containsi.js +13 -0
  25. package/server/services/builders/filters/operators/not-in.js +15 -0
  26. package/server/services/builders/filters/operators/not-null.js +13 -0
  27. package/server/services/builders/filters/operators/not.js +19 -0
  28. package/server/services/builders/filters/operators/null.js +13 -0
  29. package/server/services/builders/filters/operators/or.js +15 -0
  30. package/server/services/builders/filters/operators/starts-with.js +13 -0
  31. package/server/services/builders/generic-morph.js +41 -0
  32. package/server/services/builders/index.js +92 -0
  33. package/server/services/builders/input.js +118 -0
  34. package/server/services/builders/mutations/collection-type.js +170 -0
  35. package/server/services/builders/mutations/index.js +9 -0
  36. package/server/services/builders/mutations/single-type.js +135 -0
  37. package/server/services/builders/queries/collection-type.js +120 -0
  38. package/server/services/builders/queries/index.js +9 -0
  39. package/server/services/builders/queries/single-type.js +70 -0
  40. package/server/services/builders/relation-response-collection.js +35 -0
  41. package/server/services/builders/resolvers/association.js +64 -0
  42. package/server/services/builders/resolvers/component.js +14 -0
  43. package/server/services/builders/resolvers/dynamic-zone.js +9 -0
  44. package/server/services/builders/resolvers/index.js +18 -0
  45. package/server/services/builders/resolvers/mutation.js +33 -0
  46. package/server/services/builders/resolvers/query.js +19 -0
  47. package/server/services/builders/response-collection.js +43 -0
  48. package/server/services/builders/response.js +32 -0
  49. package/server/services/builders/type.js +370 -0
  50. package/server/services/builders/utils.js +131 -0
  51. package/server/services/constants.js +147 -0
  52. package/server/services/content-api/index.js +168 -0
  53. package/server/services/content-api/policy.js +59 -0
  54. package/server/services/content-api/register-functions/collection-type.js +72 -0
  55. package/server/services/content-api/register-functions/component.js +15 -0
  56. package/server/services/content-api/register-functions/content-type/dynamic-zones.js +36 -0
  57. package/server/services/content-api/register-functions/content-type/enums.js +33 -0
  58. package/server/services/content-api/register-functions/content-type/filters.js +15 -0
  59. package/server/services/content-api/register-functions/content-type/index.js +13 -0
  60. package/server/services/content-api/register-functions/content-type/inputs.js +21 -0
  61. package/server/services/content-api/register-functions/index.js +22 -0
  62. package/server/services/content-api/register-functions/internals.js +13 -0
  63. package/server/services/content-api/register-functions/polymorphic.js +69 -0
  64. package/server/services/content-api/register-functions/scalars.js +14 -0
  65. package/server/services/content-api/register-functions/single-type.js +72 -0
  66. package/server/services/content-api/wrap-resolvers.js +146 -0
  67. package/server/services/extension/extension.js +95 -0
  68. package/server/services/extension/index.js +5 -0
  69. package/server/services/extension/shadow-crud-manager.js +159 -0
  70. package/server/services/format/index.js +7 -0
  71. package/server/services/format/return-types.js +27 -0
  72. package/server/services/index.js +21 -0
  73. package/server/services/internals/args/index.js +11 -0
  74. package/server/services/internals/args/pagination.js +19 -0
  75. package/server/services/internals/args/publication-state.js +12 -0
  76. package/server/services/internals/args/sort.js +10 -0
  77. package/server/services/internals/helpers/get-enabled-scalars.js +15 -0
  78. package/server/services/internals/helpers/index.js +7 -0
  79. package/server/services/internals/index.js +13 -0
  80. package/server/services/internals/scalars/index.js +18 -0
  81. package/server/services/internals/scalars/time.js +35 -0
  82. package/server/services/internals/types/error.js +33 -0
  83. package/server/services/internals/types/filters.js +39 -0
  84. package/server/services/internals/types/index.js +29 -0
  85. package/server/services/internals/types/pagination.js +24 -0
  86. package/server/services/internals/types/publication-state.js +24 -0
  87. package/server/services/internals/types/response-collection-meta.js +38 -0
  88. package/server/services/type-registry.js +103 -0
  89. package/server/services/utils/attributes.js +84 -0
  90. package/server/services/utils/index.js +11 -0
  91. package/server/services/utils/mappers/entity-to-response-entity.js +12 -0
  92. package/server/services/utils/mappers/graphql-filters-to-strapi-query.js +107 -0
  93. package/server/services/utils/mappers/graphql-scalar-to-operators.js +17 -0
  94. package/server/services/utils/mappers/index.js +13 -0
  95. package/server/services/utils/mappers/strapi-scalar-to-graphql-scalar.js +24 -0
  96. package/server/services/utils/naming.js +282 -0
  97. package/strapi-admin.js +3 -0
  98. package/strapi-server.js +11 -0
  99. package/config/routes.json +0 -3
  100. package/config/schema.graphql +0 -1
  101. package/config/settings.json +0 -12
  102. package/controllers/GraphQL.js +0 -9
  103. package/hooks/graphql/defaults.json +0 -5
  104. package/hooks/graphql/index.js +0 -174
  105. package/hooks/graphql/load-config.js +0 -42
  106. package/services/build-aggregation.js +0 -565
  107. package/services/data-loaders.js +0 -55
  108. package/services/naming.js +0 -15
  109. package/services/resolvers-builder.js +0 -204
  110. package/services/schema-definitions.js +0 -131
  111. package/services/schema-generator.js +0 -178
  112. package/services/shadow-crud.js +0 -612
  113. package/services/type-builder.js +0 -311
  114. package/services/utils.js +0 -200
  115. package/types/dynamiczoneScalar.js +0 -40
  116. package/types/publication-state.js +0 -16
  117. package/types/time.js +0 -26
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "为默认API方法添加GraphQL端点",
3
+ "plugin.description.short": "为默认API方法添加GraphQL端点"
4
+ }
package/package.json CHANGED
@@ -1,38 +1,40 @@
1
1
  {
2
2
  "name": "@strapi/plugin-graphql",
3
- "version": "4.0.0-next.2",
3
+ "version": "4.0.0-next.20",
4
4
  "description": "Adds GraphQL endpoint with default API methods.",
5
5
  "strapi": {
6
+ "displayName": "GraphQL",
6
7
  "name": "graphql",
7
8
  "icon": "plug",
8
- "description": "graphql.plugin.description"
9
+ "description": "graphql.plugin.description",
10
+ "kind": "plugin"
9
11
  },
10
12
  "scripts": {
11
13
  "test": "echo \"no tests yet\""
12
14
  },
13
15
  "dependencies": {
14
- "@apollo/federation": "^0.20.7",
15
- "@graphql-tools/utils": "7.2.4",
16
- "@strapi/utils": "4.0.0-next.2",
17
- "apollo-server-koa": "2.24.0",
18
- "dataloader": "^1.4.0",
19
- "glob": "^7.1.6",
20
- "graphql": "15.5.0",
16
+ "@apollo/federation": "^0.28.0",
17
+ "@graphql-tools/schema": "8.1.2",
18
+ "@graphql-tools/utils": "^8.0.2",
19
+ "@strapi/utils": "4.0.0-next.20",
20
+ "apollo-server-core": "3.1.2",
21
+ "apollo-server-koa": "3.1.2",
22
+ "glob": "^7.1.7",
23
+ "graphql": "15.5.1",
21
24
  "graphql-depth-limit": "^1.1.0",
22
25
  "graphql-iso-date": "^3.6.1",
23
26
  "graphql-playground-middleware-koa": "^1.6.21",
24
- "graphql-tools": "4.0.8",
25
- "graphql-type-json": "0.3.2",
27
+ "graphql-type-json": "^0.3.2",
26
28
  "graphql-type-long": "^0.1.1",
27
- "graphql-upload": "11.0.0",
29
+ "graphql-upload": "12.0.0",
28
30
  "koa-compose": "^4.1.0",
29
31
  "lodash": "4.17.21",
32
+ "nexus": "1.1.0",
30
33
  "pluralize": "^8.0.0"
31
34
  },
32
35
  "devDependencies": {
33
36
  "cross-env": "^7.0.3",
34
- "koa": "^2.13.1",
35
- "rimraf": "3.0.2"
37
+ "koa": "^2.13.1"
36
38
  },
37
39
  "author": {
38
40
  "name": "A Strapi developer",
@@ -51,5 +53,5 @@
51
53
  "npm": ">=6.0.0"
52
54
  },
53
55
  "license": "SEE LICENSE IN LICENSE",
54
- "gitHead": "50849e68c7d3632eb5899c6346e33d71a211a3bd"
56
+ "gitHead": "9807c78cb7ab6373b7abb46da5ecc4980a9ea56c"
55
57
  }
@@ -0,0 +1,124 @@
1
+ 'use strict';
2
+
3
+ const { isEmpty, mergeWith, isArray } = require('lodash/fp');
4
+ const { ApolloServer } = require('apollo-server-koa');
5
+ const {
6
+ ApolloServerPluginLandingPageDisabled,
7
+ ApolloServerPluginLandingPageGraphQLPlayground,
8
+ } = require('apollo-server-core');
9
+ const depthLimit = require('graphql-depth-limit');
10
+ const { graphqlUploadKoa } = require('graphql-upload');
11
+
12
+ const merge = mergeWith((a, b) => {
13
+ if (isArray(a) && isArray(b)) {
14
+ return a.concat(b);
15
+ }
16
+ });
17
+
18
+ module.exports = async ({ strapi }) => {
19
+ // Generate the GraphQL schema for the content API
20
+ const schema = strapi
21
+ .plugin('graphql')
22
+ .service('content-api')
23
+ .buildSchema();
24
+
25
+ if (isEmpty(schema)) {
26
+ strapi.log.warn('The GraphQL schema has not been generated because it is empty');
27
+
28
+ return;
29
+ }
30
+
31
+ const { config } = strapi.plugin('graphql');
32
+
33
+ const defaultServerConfig = {
34
+ // Schema
35
+ schema,
36
+
37
+ // Initialize loaders for this request.
38
+ context: ({ ctx }) => ({
39
+ state: ctx.state,
40
+ koaContext: ctx,
41
+ }),
42
+
43
+ // Validation
44
+ validationRules: [depthLimit(config('depthLimit'))],
45
+
46
+ // Misc
47
+ cors: false,
48
+ uploads: false,
49
+ bodyParserConfig: true,
50
+
51
+ plugins: [
52
+ process.env.NODE_ENV === 'production'
53
+ ? ApolloServerPluginLandingPageDisabled()
54
+ : ApolloServerPluginLandingPageGraphQLPlayground(),
55
+ ],
56
+ };
57
+
58
+ const serverConfig = merge(defaultServerConfig, config('apolloServer', {}));
59
+
60
+ // Create a new Apollo server
61
+ const server = new ApolloServer(serverConfig);
62
+
63
+ // Link the Apollo server & the Strapi app
64
+ const path = config('endpoint', '/graphql');
65
+
66
+ // Register the upload middleware
67
+ useUploadMiddleware(strapi, path);
68
+
69
+ try {
70
+ // Since Apollo-Server v3, server.start() must be called before using server.applyMiddleware()
71
+ await server.start();
72
+ } catch (e) {
73
+ strapi.log.error('Failed to start the Apollo server', e.message);
74
+ }
75
+
76
+ strapi.server.routes([
77
+ {
78
+ method: 'ALL',
79
+ path,
80
+ handler: [
81
+ (ctx, next) => {
82
+ ctx.state.route = {
83
+ info: {
84
+ // Indicate it's a content API route
85
+ type: 'content-api',
86
+ },
87
+ };
88
+
89
+ return strapi.auth.authenticate(ctx, next);
90
+ },
91
+
92
+ // Apollo Server
93
+ server.getMiddleware({ path }),
94
+ ],
95
+ config: {
96
+ auth: false,
97
+ },
98
+ },
99
+ ]);
100
+
101
+ // Register destroy behavior
102
+ // We're doing it here instead of exposing a destroy method to the strapi-server.js
103
+ // file since we need to have access to the ApolloServer instance
104
+ strapi.plugin('graphql').destroy = async () => {
105
+ await server.stop();
106
+ };
107
+ };
108
+
109
+ /**
110
+ * Register the upload middleware powered by graphql-upload in Strapi
111
+ * @param {object} strapi
112
+ * @param {string} path
113
+ */
114
+ const useUploadMiddleware = (strapi, path) => {
115
+ const uploadMiddleware = graphqlUploadKoa();
116
+
117
+ strapi.server.app.use((ctx, next) => {
118
+ if (ctx.path === path) {
119
+ return uploadMiddleware(ctx, next);
120
+ }
121
+
122
+ return next();
123
+ });
124
+ };
@@ -0,0 +1,96 @@
1
+ 'use strict';
2
+
3
+ const { Kind, valueFromASTUntyped, GraphQLError } = require('graphql');
4
+ const { omit } = require('lodash/fp');
5
+ const { unionType, scalarType } = require('nexus');
6
+
7
+ module.exports = ({ strapi }) => {
8
+ const buildTypeDefinition = (name, components) => {
9
+ const { ERROR_TYPE_NAME } = strapi.plugin('graphql').service('constants');
10
+ const isEmpty = components.length === 0;
11
+
12
+ const componentsTypeNames = components.map(componentUID => {
13
+ const component = strapi.components[componentUID];
14
+
15
+ if (!component) {
16
+ throw new Error(
17
+ `Trying to create a dynamic zone type with an unknown component: "${componentUID}"`
18
+ );
19
+ }
20
+
21
+ return component.globalId;
22
+ });
23
+
24
+ return unionType({
25
+ name,
26
+
27
+ resolveType(obj) {
28
+ if (isEmpty) {
29
+ return ERROR_TYPE_NAME;
30
+ }
31
+
32
+ return strapi.components[obj.__component].globalId;
33
+ },
34
+
35
+ definition(t) {
36
+ t.members(...componentsTypeNames, ERROR_TYPE_NAME);
37
+ },
38
+ });
39
+ };
40
+
41
+ const buildInputDefinition = (name, components) => {
42
+ const parseData = value => {
43
+ const component = Object.values(strapi.components).find(
44
+ component => component.globalId === value.__typename
45
+ );
46
+
47
+ if (!component) {
48
+ throw new GraphQLError(
49
+ `Component not found. expected one of: ${components
50
+ .map(uid => strapi.components[uid].globalId)
51
+ .join(', ')}`
52
+ );
53
+ }
54
+
55
+ return {
56
+ __component: component.uid,
57
+ ...omit(['__typename'], value),
58
+ };
59
+ };
60
+
61
+ return scalarType({
62
+ name,
63
+
64
+ serialize: value => value,
65
+
66
+ parseValue: value => parseData(value),
67
+
68
+ parseLiteral(ast, variables) {
69
+ if (ast.kind !== Kind.OBJECT) {
70
+ return undefined;
71
+ }
72
+
73
+ const value = valueFromASTUntyped(ast, variables);
74
+ return parseData(value);
75
+ },
76
+ });
77
+ };
78
+
79
+ return {
80
+ /**
81
+ * Build a Nexus dynamic zone type from a Strapi dz attribute
82
+ * @param {object} definition - The definition of the dynamic zone
83
+ * @param {string} name - the name of the dynamic zone
84
+ * @param {string} inputName - the name of the dynamic zone's input
85
+ * @return {[NexusUnionTypeDef, NexusScalarTypeDef]}
86
+ */
87
+ buildDynamicZoneDefinition(definition, name, inputName) {
88
+ const { components } = definition;
89
+
90
+ const typeDefinition = buildTypeDefinition(name, components);
91
+ const inputDefinition = buildInputDefinition(inputName, components);
92
+
93
+ return [typeDefinition, inputDefinition];
94
+ },
95
+ };
96
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ function buildEntityMetaDefinition(/*contentType*/) {}
4
+
5
+ module.exports = () => ({
6
+ buildEntityMetaDefinition,
7
+ });
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ const { objectType } = require('nexus');
4
+ const { prop, identity, isEmpty } = require('lodash/fp');
5
+
6
+ module.exports = ({ strapi }) => {
7
+ const { naming } = strapi.plugin('graphql').service('utils');
8
+
9
+ return {
10
+ /**
11
+ * Build a higher level type for a content type which contains the attributes, the ID and the metadata
12
+ * @param {object} contentType The content type which will be used to build its entity type
13
+ * @return {NexusObjectTypeDef}
14
+ */
15
+ buildEntityDefinition(contentType) {
16
+ const { attributes } = contentType;
17
+
18
+ const name = naming.getEntityName(contentType);
19
+ const typeName = naming.getTypeName(contentType);
20
+
21
+ return objectType({
22
+ name,
23
+
24
+ definition(t) {
25
+ // Keep the ID attribute at the top level
26
+ t.id('id', { resolve: prop('id') });
27
+
28
+ if (!isEmpty(attributes)) {
29
+ // Keep the fetched object into a dedicated `attributes` field
30
+ // TODO: [v4] precise why we keep the ID
31
+ t.field('attributes', {
32
+ type: typeName,
33
+ resolve: identity,
34
+ });
35
+ }
36
+
37
+ // todo[v4]: add the meta field to the entity when there will be data in it (can't add an empty type for now)
38
+ // t.field('meta', { type: utils.getEntityMetaName(contentType) });
39
+ },
40
+ });
41
+ },
42
+ };
43
+ };
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ const { enumType } = require('nexus');
4
+ const { set } = require('lodash/fp');
5
+
6
+ /**
7
+ * Build a Nexus enum type from a Strapi enum attribute
8
+ * @param {object} definition - The definition of the enum
9
+ * @param {string[]} definition.enum - The params of the enum
10
+ * @param {string} name - The name of the enum
11
+ * @return {NexusEnumTypeDef}
12
+ */
13
+ const buildEnumTypeDefinition = (definition, name) => {
14
+ return enumType({
15
+ name,
16
+ // In Strapi V3, the key of an enum is also its value
17
+ // todo[V4]: allow passing an object of key/value instead of an array
18
+ members: definition.enum.reduce((acc, value) => set(value, value, acc), {}),
19
+ });
20
+ };
21
+
22
+ module.exports = () => ({
23
+ buildEnumTypeDefinition,
24
+ });
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+
3
+ const { inputObjectType } = require('nexus');
4
+
5
+ module.exports = ({ strapi }) => {
6
+ const rootLevelOperators = () => {
7
+ const { operators } = strapi.plugin('graphql').service('builders').filters;
8
+
9
+ return [operators.and, operators.or, operators.not];
10
+ };
11
+
12
+ const buildContentTypeFilters = contentType => {
13
+ const utils = strapi.plugin('graphql').service('utils');
14
+ const extension = strapi.plugin('graphql').service('extension');
15
+
16
+ const { getFiltersInputTypeName } = utils.naming;
17
+ const { isStrapiScalar, isRelation } = utils.attributes;
18
+
19
+ const { attributes } = contentType;
20
+
21
+ const filtersTypeName = getFiltersInputTypeName(contentType);
22
+
23
+ return inputObjectType({
24
+ name: filtersTypeName,
25
+
26
+ definition(t) {
27
+ const validAttributes = Object.entries(attributes).filter(([attributeName]) =>
28
+ extension
29
+ .shadowCRUD(contentType.uid)
30
+ .field(attributeName)
31
+ .hasFiltersEnabeld()
32
+ );
33
+
34
+ // Add every defined attribute
35
+ for (const [attributeName, attribute] of validAttributes) {
36
+ // Handle scalars
37
+ if (isStrapiScalar(attribute)) {
38
+ addScalarAttribute(t, attributeName, attribute);
39
+ }
40
+
41
+ // Handle relations
42
+ else if (isRelation(attribute)) {
43
+ addRelationalAttribute(t, attributeName, attribute);
44
+ }
45
+ }
46
+
47
+ // Conditional clauses
48
+ for (const operator of rootLevelOperators()) {
49
+ operator.add(t, filtersTypeName);
50
+ }
51
+ },
52
+ });
53
+ };
54
+
55
+ const addScalarAttribute = (builder, attributeName, attribute) => {
56
+ const { naming, mappers } = strapi.plugin('graphql').service('utils');
57
+
58
+ const gqlType = mappers.strapiScalarToGraphQLScalar(attribute.type);
59
+
60
+ builder.field(attributeName, { type: naming.getScalarFilterInputTypeName(gqlType) });
61
+ };
62
+
63
+ const addRelationalAttribute = (builder, attributeName, attribute) => {
64
+ const utils = strapi.plugin('graphql').service('utils');
65
+ const extension = strapi.plugin('graphql').service('extension');
66
+ const { getFiltersInputTypeName } = utils.naming;
67
+ const { isMorphRelation } = utils.attributes;
68
+
69
+ const model = strapi.getModel(attribute.target);
70
+
71
+ // If there is no model corresponding to the attribute configuration
72
+ // or if the attribute is a polymorphic relation, then ignore it
73
+ if (!model || isMorphRelation(attribute)) return;
74
+
75
+ // If the target model is disabled, then ignore it too
76
+ if (extension.shadowCRUD(model.uid).isDisabled()) return;
77
+
78
+ builder.field(attributeName, { type: getFiltersInputTypeName(model) });
79
+ };
80
+
81
+ return {
82
+ buildContentTypeFilters,
83
+ };
84
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ const contentType = require('./content-type');
4
+
5
+ module.exports = context => ({
6
+ ...contentType(context),
7
+ });
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ const { list } = require('nexus');
4
+
5
+ const AND_FIELD_NAME = 'and';
6
+
7
+ module.exports = () => ({
8
+ fieldName: AND_FIELD_NAME,
9
+
10
+ strapiOperator: '$and',
11
+
12
+ add(t, type) {
13
+ t.field(AND_FIELD_NAME, { type: list(type) });
14
+ },
15
+ });
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ const { list } = require('nexus');
4
+
5
+ const BETWEEN_FIELD_NAME = 'between';
6
+
7
+ module.exports = () => ({
8
+ fieldName: BETWEEN_FIELD_NAME,
9
+
10
+ strapiOperator: '$between',
11
+
12
+ add(t, type) {
13
+ t.field(BETWEEN_FIELD_NAME, { type: list(type) });
14
+ },
15
+ });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const CONTAINS_FIELD_NAME = 'contains';
4
+
5
+ module.exports = () => ({
6
+ fieldName: CONTAINS_FIELD_NAME,
7
+
8
+ strapiOperator: '$contains',
9
+
10
+ add(t, type) {
11
+ t.field(CONTAINS_FIELD_NAME, { type });
12
+ },
13
+ });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const CONTAINSI_FIELD_NAME = 'containsi';
4
+
5
+ module.exports = () => ({
6
+ fieldName: CONTAINSI_FIELD_NAME,
7
+
8
+ strapiOperator: '$containsi',
9
+
10
+ add(t, type) {
11
+ t.field(CONTAINSI_FIELD_NAME, { type });
12
+ },
13
+ });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const ENDS_WITH_FIELD_NAME = 'endsWith';
4
+
5
+ module.exports = () => ({
6
+ fieldName: ENDS_WITH_FIELD_NAME,
7
+
8
+ strapiOperator: '$endsWith',
9
+
10
+ add(t, type) {
11
+ t.field(ENDS_WITH_FIELD_NAME, { type });
12
+ },
13
+ });
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ const EQ_FIELD_NAME = 'eq';
4
+
5
+ module.exports = ({ strapi }) => ({
6
+ fieldName: EQ_FIELD_NAME,
7
+
8
+ strapiOperator: '$eq',
9
+
10
+ add(t, type) {
11
+ const { GRAPHQL_SCALARS } = strapi.plugin('graphql').service('constants');
12
+
13
+ if (!GRAPHQL_SCALARS.includes(type)) {
14
+ throw new Error(`Can't use "${EQ_FIELD_NAME}" operator. "${type}" is not a valid scalar`);
15
+ }
16
+
17
+ t.field(EQ_FIELD_NAME, { type });
18
+ },
19
+ });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const GT_FIELD_NAME = 'gt';
4
+
5
+ module.exports = () => ({
6
+ fieldName: GT_FIELD_NAME,
7
+
8
+ strapiOperator: '$gt',
9
+
10
+ add(t, type) {
11
+ t.field(GT_FIELD_NAME, { type });
12
+ },
13
+ });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const GTE_FIELD_NAME = 'gte';
4
+
5
+ module.exports = () => ({
6
+ fieldName: GTE_FIELD_NAME,
7
+
8
+ strapiOperator: '$gte',
9
+
10
+ add(t, type) {
11
+ t.field(GTE_FIELD_NAME, { type });
12
+ },
13
+ });
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ const { list } = require('nexus');
4
+
5
+ const IN_FIELD_NAME = 'in';
6
+
7
+ module.exports = () => ({
8
+ fieldName: IN_FIELD_NAME,
9
+
10
+ strapiOperator: '$in',
11
+
12
+ add(t, type) {
13
+ t.field(IN_FIELD_NAME, { type: list(type) });
14
+ },
15
+ });
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ const { mapValues } = require('lodash/fp');
4
+
5
+ const operators = {
6
+ and: require('./and'),
7
+ or: require('./or'),
8
+ not: require('./not'),
9
+
10
+ eq: require('./eq'),
11
+ ne: require('./ne'),
12
+
13
+ startsWith: require('./starts-with'),
14
+ endsWith: require('./ends-with'),
15
+
16
+ contains: require('./contains'),
17
+ notContains: require('./not-contains'),
18
+
19
+ containsi: require('./containsi'),
20
+ notContainsi: require('./not-containsi'),
21
+
22
+ gt: require('./gt'),
23
+ gte: require('./gte'),
24
+
25
+ lt: require('./lt'),
26
+ lte: require('./lte'),
27
+
28
+ null: require('./null'),
29
+ notNull: require('./not-null'),
30
+
31
+ in: require('./in'),
32
+ notIn: require('./not-in'),
33
+
34
+ between: require('./between'),
35
+ };
36
+
37
+ // Instantiate every operator with the Strapi instance
38
+ module.exports = context => mapValues(opCtor => opCtor(context), operators);
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const LT_FIELD_NAME = 'lt';
4
+
5
+ module.exports = () => ({
6
+ fieldName: LT_FIELD_NAME,
7
+
8
+ strapiOperator: '$lt',
9
+
10
+ add(t, type) {
11
+ t.field(LT_FIELD_NAME, { type });
12
+ },
13
+ });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const LTE_FIELD_NAME = 'lte';
4
+
5
+ module.exports = () => ({
6
+ fieldName: LTE_FIELD_NAME,
7
+
8
+ strapiOperator: '$lte',
9
+
10
+ add(t, type) {
11
+ t.field(LTE_FIELD_NAME, { type });
12
+ },
13
+ });
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const NE_FIELD_NAME = 'ne';
4
+
5
+ module.exports = () => ({
6
+ fieldName: NE_FIELD_NAME,
7
+
8
+ strapiOperator: '$ne',
9
+
10
+ add(t, type) {
11
+ t.field(NE_FIELD_NAME, { type });
12
+ },
13
+ });