@strapi/plugin-graphql 4.20.4 → 5.0.0-alpha.0

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 (90) hide show
  1. package/dist/admin/index.js +21 -19
  2. package/dist/admin/index.js.map +1 -1
  3. package/dist/admin/index.mjs +21 -19
  4. package/dist/admin/index.mjs.map +1 -1
  5. package/dist/server/index.js +440 -296
  6. package/dist/server/index.js.map +1 -1
  7. package/dist/server/index.mjs +438 -296
  8. package/dist/server/index.mjs.map +1 -1
  9. package/dist/server/src/bootstrap.d.ts.map +1 -1
  10. package/dist/server/src/config/default-config.d.ts +1 -0
  11. package/dist/server/src/config/default-config.d.ts.map +1 -1
  12. package/dist/server/src/config/index.d.ts +1 -0
  13. package/dist/server/src/config/index.d.ts.map +1 -1
  14. package/dist/server/src/format-graphql-error.d.ts +7 -3
  15. package/dist/server/src/format-graphql-error.d.ts.map +1 -1
  16. package/dist/server/src/index.d.ts +31 -17
  17. package/dist/server/src/index.d.ts.map +1 -1
  18. package/dist/server/src/services/builders/entity.d.ts.map +1 -1
  19. package/dist/server/src/services/builders/index.d.ts +9 -5
  20. package/dist/server/src/services/builders/index.d.ts.map +1 -1
  21. package/dist/server/src/services/builders/mutations/collection-type.d.ts.map +1 -1
  22. package/dist/server/src/services/builders/mutations/single-type.d.ts.map +1 -1
  23. package/dist/server/src/services/builders/queries/collection-type.d.ts.map +1 -1
  24. package/dist/server/src/services/builders/queries/single-type.d.ts.map +1 -1
  25. package/dist/server/src/services/builders/relation-response-collection.d.ts.map +1 -1
  26. package/dist/server/src/services/builders/resolvers/association.d.ts.map +1 -1
  27. package/dist/server/src/services/builders/resolvers/component.d.ts.map +1 -1
  28. package/dist/server/src/services/builders/resolvers/index.d.ts +9 -33
  29. package/dist/server/src/services/builders/resolvers/index.d.ts.map +1 -1
  30. package/dist/server/src/services/builders/resolvers/pagination.d.ts +11 -0
  31. package/dist/server/src/services/builders/resolvers/pagination.d.ts.map +1 -0
  32. package/dist/server/src/services/builders/resolvers/query.d.ts +3 -14
  33. package/dist/server/src/services/builders/resolvers/query.d.ts.map +1 -1
  34. package/dist/server/src/services/builders/response-collection.d.ts.map +1 -1
  35. package/dist/server/src/services/builders/type.d.ts.map +1 -1
  36. package/dist/server/src/services/builders/utils.d.ts +11 -13
  37. package/dist/server/src/services/builders/utils.d.ts.map +1 -1
  38. package/dist/server/src/services/constants.d.ts +2 -1
  39. package/dist/server/src/services/constants.d.ts.map +1 -1
  40. package/dist/server/src/services/content-api/index.d.ts.map +1 -1
  41. package/dist/server/src/services/content-api/policy.d.ts +1 -1
  42. package/dist/server/src/services/content-api/policy.d.ts.map +1 -1
  43. package/dist/server/src/services/content-api/register-functions/{content-type/dynamic-zones.d.ts → dynamic-zones.d.ts} +1 -1
  44. package/dist/server/src/services/content-api/register-functions/dynamic-zones.d.ts.map +1 -0
  45. package/dist/server/src/services/content-api/register-functions/{content-type/enums.d.ts → enums.d.ts} +1 -1
  46. package/dist/server/src/services/content-api/register-functions/enums.d.ts.map +1 -0
  47. package/dist/server/src/services/content-api/register-functions/{content-type/filters.d.ts → filters.d.ts} +1 -1
  48. package/dist/server/src/services/content-api/register-functions/filters.d.ts.map +1 -0
  49. package/dist/server/src/services/content-api/register-functions/index.d.ts +5 -2
  50. package/dist/server/src/services/content-api/register-functions/index.d.ts.map +1 -1
  51. package/dist/server/src/services/content-api/register-functions/{content-type/inputs.d.ts → inputs.d.ts} +1 -1
  52. package/dist/server/src/services/content-api/register-functions/inputs.d.ts.map +1 -0
  53. package/dist/server/src/services/index.d.ts +30 -17
  54. package/dist/server/src/services/index.d.ts.map +1 -1
  55. package/dist/server/src/services/internals/args/index.d.ts +1 -1
  56. package/dist/server/src/services/internals/args/{publication-state.d.ts → publication-status.d.ts} +1 -1
  57. package/dist/server/src/services/internals/args/publication-status.d.ts.map +1 -0
  58. package/dist/server/src/services/internals/index.d.ts +14 -10
  59. package/dist/server/src/services/internals/index.d.ts.map +1 -1
  60. package/dist/server/src/services/internals/scalars/index.d.ts +4 -5
  61. package/dist/server/src/services/internals/scalars/index.d.ts.map +1 -1
  62. package/dist/server/src/services/internals/scalars/time.d.ts +1 -1
  63. package/dist/server/src/services/internals/scalars/time.d.ts.map +1 -1
  64. package/dist/server/src/services/internals/types/delete-mutation-response.d.ts +6 -0
  65. package/dist/server/src/services/internals/types/delete-mutation-response.d.ts.map +1 -0
  66. package/dist/server/src/services/internals/types/index.d.ts +9 -4
  67. package/dist/server/src/services/internals/types/index.d.ts.map +1 -1
  68. package/dist/server/src/services/internals/types/publication-status.d.ts +10 -0
  69. package/dist/server/src/services/internals/types/publication-status.d.ts.map +1 -0
  70. package/dist/server/src/services/internals/types/response-collection-meta.d.ts.map +1 -1
  71. package/dist/server/src/services/utils/index.d.ts +5 -1
  72. package/dist/server/src/services/utils/index.d.ts.map +1 -1
  73. package/dist/server/src/services/utils/naming.d.ts +1 -0
  74. package/dist/server/src/services/utils/naming.d.ts.map +1 -1
  75. package/dist/server/src/services/utils/playground.d.ts +6 -0
  76. package/dist/server/src/services/utils/playground.d.ts.map +1 -0
  77. package/package.json +22 -20
  78. package/dist/server/src/services/builders/entity-meta.d.ts +0 -6
  79. package/dist/server/src/services/builders/entity-meta.d.ts.map +0 -1
  80. package/dist/server/src/services/builders/resolvers/mutation.d.ts +0 -25
  81. package/dist/server/src/services/builders/resolvers/mutation.d.ts.map +0 -1
  82. package/dist/server/src/services/content-api/register-functions/content-type/dynamic-zones.d.ts.map +0 -1
  83. package/dist/server/src/services/content-api/register-functions/content-type/enums.d.ts.map +0 -1
  84. package/dist/server/src/services/content-api/register-functions/content-type/filters.d.ts.map +0 -1
  85. package/dist/server/src/services/content-api/register-functions/content-type/index.d.ts +0 -24
  86. package/dist/server/src/services/content-api/register-functions/content-type/index.d.ts.map +0 -1
  87. package/dist/server/src/services/content-api/register-functions/content-type/inputs.d.ts.map +0 -1
  88. package/dist/server/src/services/internals/args/publication-state.d.ts.map +0 -1
  89. package/dist/server/src/services/internals/types/publication-state.d.ts +0 -10
  90. package/dist/server/src/services/internals/types/publication-state.d.ts.map +0 -1
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  const fp = require("lodash/fp");
3
- const apolloServerKoa = require("apollo-server-koa");
4
- const apolloServerCore = require("apollo-server-core");
3
+ const server = require("@apollo/server");
4
+ const _default = require("@apollo/server/plugin/landingPage/default");
5
+ const koa = require("@as-integrations/koa");
5
6
  const depthLimit = require("graphql-depth-limit");
6
- const graphqlUpload = require("graphql-upload");
7
+ const bodyParser = require("koa-bodyparser");
8
+ const cors = require("@koa/cors");
7
9
  const utils$2 = require("@strapi/utils");
10
+ const errors = require("@apollo/server/errors");
8
11
  const graphql = require("graphql");
9
12
  const utils$3 = require("@graphql-tools/utils");
10
13
  const nexus = require("nexus");
@@ -30,13 +33,16 @@ function _interopNamespace(e) {
30
33
  return Object.freeze(n);
31
34
  }
32
35
  const depthLimit__default = /* @__PURE__ */ _interopDefault(depthLimit);
36
+ const bodyParser__default = /* @__PURE__ */ _interopDefault(bodyParser);
37
+ const cors__default = /* @__PURE__ */ _interopDefault(cors);
33
38
  const nexus__namespace = /* @__PURE__ */ _interopNamespace(nexus);
34
39
  const defaultConfig = {
35
40
  shadowCRUD: true,
36
41
  endpoint: "/graphql",
37
42
  subscriptions: false,
38
43
  maxLimit: -1,
39
- apolloServer: {}
44
+ apolloServer: {},
45
+ v4CompatibilityMode: process.env.STRAPI_GRAPHQL_V4_COMPATIBILITY_MODE ?? false
40
46
  };
41
47
  const config = {
42
48
  default: defaultConfig
@@ -46,41 +52,49 @@ const formatToCode = (name) => `STRAPI_${fp.toUpper(fp.snakeCase(name))}`;
46
52
  const formatErrorToExtension = (error2) => ({
47
53
  error: fp.pick(["name", "message", "details"])(error2)
48
54
  });
49
- function formatGraphqlError(error2) {
50
- const { originalError } = error2;
55
+ function createFormattedError(formattedError, message, code, originalError) {
56
+ const options = {
57
+ ...formattedError,
58
+ extensions: {
59
+ ...formattedError.extensions,
60
+ ...formatErrorToExtension(originalError),
61
+ code
62
+ }
63
+ };
64
+ return new graphql.GraphQLError(message, options);
65
+ }
66
+ function formatGraphqlError(formattedError, error2) {
67
+ const originalError = errors.unwrapResolverError(error2);
51
68
  if (fp.isEmpty(originalError)) {
52
- return error2;
69
+ return formattedError;
53
70
  }
71
+ const { message = "", name = "UNKNOWN" } = originalError;
54
72
  if (originalError instanceof ForbiddenError$1 || originalError instanceof UnauthorizedError) {
55
- return new apolloServerKoa.ForbiddenError(originalError.message, formatErrorToExtension(originalError));
73
+ return createFormattedError(formattedError, message, "FORBIDDEN", originalError);
56
74
  }
57
75
  if (originalError instanceof ValidationError$3) {
58
- return new apolloServerKoa.UserInputError(originalError.message, formatErrorToExtension(originalError));
76
+ return createFormattedError(formattedError, message, "BAD_USER_INPUT", originalError);
59
77
  }
60
78
  if (originalError instanceof ApplicationError$5 || originalError instanceof HttpError) {
61
- const name = formatToCode(originalError.name);
62
- return new apolloServerKoa.ApolloError(originalError.message, name, formatErrorToExtension(originalError));
79
+ const errorName = formatToCode(name);
80
+ return createFormattedError(formattedError, message, errorName, originalError);
63
81
  }
64
- if (originalError instanceof apolloServerKoa.ApolloError || originalError instanceof graphql.GraphQLError) {
65
- return error2;
82
+ if (originalError instanceof graphql.GraphQLError) {
83
+ return formattedError;
66
84
  }
67
85
  strapi.log.error(originalError);
68
- return new apolloServerKoa.ApolloError("Internal Server Error", "INTERNAL_SERVER_ERROR");
86
+ return createFormattedError(
87
+ new graphql.GraphQLError("Internal Server Error"),
88
+ "Internal Server Error",
89
+ "INTERNAL_SERVER_ERROR",
90
+ originalError
91
+ );
69
92
  }
70
93
  const merge = fp.mergeWith((a, b) => {
71
94
  if (fp.isArray(a) && fp.isArray(b)) {
72
95
  return a.concat(b);
73
96
  }
74
97
  });
75
- const useUploadMiddleware = (strapi2, path) => {
76
- const uploadMiddleware = graphqlUpload.graphqlUploadKoa();
77
- strapi2.server.app.use((ctx, next) => {
78
- if (ctx.path === path) {
79
- return uploadMiddleware(ctx, next);
80
- }
81
- return next();
82
- });
83
- };
84
98
  async function bootstrap({ strapi: strapi2 }) {
85
99
  const schema = strapi2.plugin("graphql").service("content-api").buildSchema();
86
100
  if (fp.isEmpty(schema)) {
@@ -89,14 +103,18 @@ async function bootstrap({ strapi: strapi2 }) {
89
103
  }
90
104
  const { config: config2 } = strapi2.plugin("graphql");
91
105
  const path = config2("endpoint");
106
+ const playgroundEnabled = !(process.env.NODE_ENV === "production" && !config2("playgroundAlways"));
107
+ let landingPage;
108
+ if (playgroundEnabled) {
109
+ landingPage = _default.ApolloServerPluginLandingPageLocalDefault();
110
+ strapi2.log.debug("Using Apollo sandbox landing page");
111
+ } else {
112
+ landingPage = _default.ApolloServerPluginLandingPageProductionDefault();
113
+ strapi2.log.debug("Using Apollo production landing page");
114
+ }
92
115
  const defaultServerConfig = {
93
116
  // Schema
94
117
  schema,
95
- // Initialize loaders for this request.
96
- context: ({ ctx }) => ({
97
- state: ctx.state,
98
- koaContext: ctx
99
- }),
100
118
  // Validation
101
119
  validationRules: [depthLimit__default.default(config2("depthLimit"))],
102
120
  // Errors
@@ -105,52 +123,68 @@ async function bootstrap({ strapi: strapi2 }) {
105
123
  cors: false,
106
124
  uploads: false,
107
125
  bodyParserConfig: true,
108
- plugins: [
109
- process.env.NODE_ENV === "production" && !config2("playgroundAlways") ? apolloServerCore.ApolloServerPluginLandingPageDisabled() : apolloServerCore.ApolloServerPluginLandingPageGraphQLPlayground()
110
- ],
126
+ // send 400 http status instead of 200 for input validation errors
127
+ status400ForVariableCoercionErrors: true,
128
+ plugins: [landingPage],
111
129
  cache: "bounded"
112
130
  };
113
- const serverConfig = merge(defaultServerConfig, config2("apolloServer"));
114
- const server = new apolloServerKoa.ApolloServer(serverConfig);
115
- useUploadMiddleware(strapi2, path);
131
+ const serverConfig = merge(
132
+ defaultServerConfig,
133
+ config2("apolloServer")
134
+ );
135
+ const server$1 = new server.ApolloServer(serverConfig);
116
136
  try {
117
- await server.start();
137
+ await server$1.start();
118
138
  } catch (error2) {
119
139
  if (error2 instanceof Error) {
120
140
  strapi2.log.error("Failed to start the Apollo server", error2.message);
121
141
  }
122
142
  throw error2;
123
143
  }
144
+ const handler = [];
145
+ if (cors__default.default) {
146
+ handler.push(cors__default.default());
147
+ }
148
+ if (fp.isObject(serverConfig.bodyParserConfig)) {
149
+ handler.push(bodyParser__default.default(serverConfig.bodyParserConfig));
150
+ } else if (serverConfig.bodyParserConfig) {
151
+ handler.push(bodyParser__default.default());
152
+ } else {
153
+ strapi2.log.debug("Body parser has been disabled for Apollo server");
154
+ }
155
+ handler.push((ctx, next) => {
156
+ ctx.state.route = {
157
+ info: {
158
+ // Indicate it's a content API route
159
+ type: "content-api"
160
+ }
161
+ };
162
+ if (ctx.request.method === "GET") {
163
+ return next();
164
+ }
165
+ return strapi2.auth.authenticate(ctx, next);
166
+ });
167
+ handler.push(
168
+ koa.koaMiddleware(server$1, {
169
+ // Initialize loaders for this request.
170
+ context: async ({ ctx }) => ({
171
+ state: ctx.state,
172
+ koaContext: ctx
173
+ })
174
+ })
175
+ );
124
176
  strapi2.server.routes([
125
177
  {
126
178
  method: "ALL",
127
179
  path,
128
- handler: [
129
- (ctx, next) => {
130
- ctx.state.route = {
131
- info: {
132
- // Indicate it's a content API route
133
- type: "content-api"
134
- }
135
- };
136
- if (ctx.request.method === "GET")
137
- return next();
138
- return strapi2.auth.authenticate(ctx, next);
139
- },
140
- // Apollo Server
141
- server.getMiddleware({
142
- path,
143
- cors: serverConfig.cors,
144
- bodyParserConfig: serverConfig.bodyParserConfig
145
- })
146
- ],
180
+ handler,
147
181
  config: {
148
182
  auth: false
149
183
  }
150
184
  }
151
185
  ]);
152
186
  strapi2.plugin("graphql").destroy = async () => {
153
- await server.stop();
187
+ await server$1.stop();
154
188
  };
155
189
  }
156
190
  const { PolicyError } = utils$2.errors;
@@ -454,7 +488,7 @@ const registerInternals = ({ registry, strapi: strapi2 }) => {
454
488
  registry.registerMany(Object.entries(definitions), { kind });
455
489
  }
456
490
  };
457
- const registerDynamicZonesDefinition$1 = (contentType2, {
491
+ const registerDynamicZonesDefinition = (contentType2, {
458
492
  registry,
459
493
  strapi: strapi2,
460
494
  builders: builders2
@@ -483,7 +517,7 @@ const registerDynamicZonesDefinition$1 = (contentType2, {
483
517
  registry.register(dzInputName, input, { kind: KINDS2.input, ...baseConfig });
484
518
  }
485
519
  };
486
- const registerEnumsDefinition$1 = (contentType2, {
520
+ const registerEnumsDefinition = (contentType2, {
487
521
  registry,
488
522
  strapi: strapi2,
489
523
  builders: builders2
@@ -510,7 +544,7 @@ const registerEnumsDefinition$1 = (contentType2, {
510
544
  });
511
545
  }
512
546
  };
513
- const registerInputsDefinition$1 = (contentType2, {
547
+ const registerInputsDefinition = (contentType2, {
514
548
  registry,
515
549
  strapi: strapi2,
516
550
  builders: builders2
@@ -526,7 +560,7 @@ const registerInputsDefinition$1 = (contentType2, {
526
560
  const definition = builders2.buildInputType(contentType2);
527
561
  registry.register(type, definition, { kind: KINDS2.input, contentType: contentType2 });
528
562
  };
529
- const registerFiltersDefinition$1 = (contentType2, {
563
+ const registerFiltersDefinition = (contentType2, {
530
564
  registry,
531
565
  strapi: strapi2,
532
566
  builders: builders2
@@ -538,18 +572,6 @@ const registerFiltersDefinition$1 = (contentType2, {
538
572
  const definition = builders2.buildContentTypeFilters(contentType2);
539
573
  registry.register(type, definition, { kind: KINDS2.filtersInput, contentType: contentType2 });
540
574
  };
541
- const contentType$1 = {
542
- registerDynamicZonesDefinition: registerDynamicZonesDefinition$1,
543
- registerFiltersDefinition: registerFiltersDefinition$1,
544
- registerInputsDefinition: registerInputsDefinition$1,
545
- registerEnumsDefinition: registerEnumsDefinition$1
546
- };
547
- const {
548
- registerEnumsDefinition,
549
- registerInputsDefinition,
550
- registerFiltersDefinition,
551
- registerDynamicZonesDefinition
552
- } = contentType$1;
553
575
  const contentAPI = ({ strapi: strapi2 }) => {
554
576
  const { mergeSchemas, addResolversToSchema } = require("@graphql-tools/schema");
555
577
  const { service: getGraphQLService } = strapi2.plugin("graphql");
@@ -736,7 +758,7 @@ const strapiScalarToGraphQLScalar = ({ strapi: strapi2 }) => {
736
758
  }
737
759
  };
738
760
  };
739
- const virtualScalarAttributes = ["id"];
761
+ const virtualScalarAttributes = ["id", "documentId"];
740
762
  const graphQLFiltersToStrapiQuery = ({ strapi: strapi2 }) => {
741
763
  const { service: getService } = strapi2.plugin("graphql");
742
764
  const recursivelyReplaceScalarOperators = (data) => {
@@ -950,6 +972,9 @@ const naming = ({ strapi: strapi2 }) => {
950
972
  plurality: "plural",
951
973
  firstLetterCase: "lower"
952
974
  });
975
+ const getFindConnectionQueryName = (contentType2) => {
976
+ return `${getFindQueryName(contentType2)}_connection`;
977
+ };
953
978
  const getFindOneQueryName = buildCustomTypeNameGenerator({ firstLetterCase: "lower" });
954
979
  const getCreateMutationTypeName = buildCustomTypeNameGenerator({
955
980
  prefix: "create",
@@ -987,16 +1012,26 @@ const naming = ({ strapi: strapi2 }) => {
987
1012
  getFindOneQueryName,
988
1013
  getCreateMutationTypeName,
989
1014
  getUpdateMutationTypeName,
990
- getDeleteMutationTypeName
1015
+ getDeleteMutationTypeName,
1016
+ getFindConnectionQueryName
1017
+ };
1018
+ };
1019
+ const playground = (ctx) => {
1020
+ return {
1021
+ isEnabled() {
1022
+ return !(process.env.NODE_ENV === "production" && !ctx.strapi.plugin("graphql").config("playgroundAlways"));
1023
+ }
991
1024
  };
992
1025
  };
993
1026
  const utils$1 = (context) => ({
1027
+ playground: playground(context),
994
1028
  naming: naming(context),
995
1029
  attributes: attributes(context),
996
1030
  mappers: mappers(context)
997
1031
  });
998
1032
  const PAGINATION_TYPE_NAME = "Pagination";
999
- const PUBLICATION_STATE_TYPE_NAME = "PublicationState";
1033
+ const DELETE_MUTATION_RESPONSE_TYPE_NAME = "DeleteMutationResponse";
1034
+ const PUBLICATION_STATUS_TYPE_NAME = "PublicationStatus";
1000
1035
  const ERROR_TYPE_NAME = "Error";
1001
1036
  const RESPONSE_COLLECTION_META_TYPE_NAME = "ResponseCollectionMeta";
1002
1037
  const GRAPHQL_SCALARS = [
@@ -1117,7 +1152,8 @@ const ERROR_CODES = {
1117
1152
  const constants = () => ({
1118
1153
  PAGINATION_TYPE_NAME,
1119
1154
  RESPONSE_COLLECTION_META_TYPE_NAME,
1120
- PUBLICATION_STATE_TYPE_NAME,
1155
+ DELETE_MUTATION_RESPONSE_TYPE_NAME,
1156
+ PUBLICATION_STATUS_TYPE_NAME,
1121
1157
  GRAPHQL_SCALARS,
1122
1158
  STRAPI_SCALARS,
1123
1159
  GENERIC_MORPH_TYPENAME,
@@ -1131,11 +1167,11 @@ const SortArg = nexus.arg({
1131
1167
  type: nexus.list("String"),
1132
1168
  default: []
1133
1169
  });
1134
- const publicationState$1 = ({ strapi: strapi2 }) => {
1135
- const { PUBLICATION_STATE_TYPE_NAME: PUBLICATION_STATE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1170
+ const publicationStatus$1 = ({ strapi: strapi2 }) => {
1171
+ const { PUBLICATION_STATUS_TYPE_NAME: PUBLICATION_STATUS_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1136
1172
  return nexus.arg({
1137
- type: PUBLICATION_STATE_TYPE_NAME2,
1138
- default: "live"
1173
+ type: PUBLICATION_STATUS_TYPE_NAME2,
1174
+ default: "published"
1139
1175
  });
1140
1176
  };
1141
1177
  const PaginationInputType = nexus.inputObjectType({
@@ -1154,7 +1190,7 @@ const PaginationArg = nexus.arg({
1154
1190
  const args = (context) => ({
1155
1191
  SortArg,
1156
1192
  PaginationArg,
1157
- PublicationStateArg: publicationState$1(context)
1193
+ PublicationStatusArg: publicationStatus$1(context)
1158
1194
  });
1159
1195
  const { ValidationError: ValidationError$2 } = utils$2.errors;
1160
1196
  const TimeScalar = new graphql.GraphQLScalarType({
@@ -1188,8 +1224,7 @@ const scalars = () => ({
1188
1224
  DateTime: nexus.asNexusMethod(graphqlScalars.GraphQLDateTime, "dateTime"),
1189
1225
  Time: nexus.asNexusMethod(TimeScalar, "time"),
1190
1226
  Date: nexus.asNexusMethod(graphqlScalars.GraphQLDate, "date"),
1191
- Long: nexus.asNexusMethod(graphqlScalars.GraphQLLong, "long"),
1192
- Upload: nexus.asNexusMethod(graphqlUpload.GraphQLUpload, "upload")
1227
+ Long: nexus.asNexusMethod(graphqlScalars.GraphQLLong, "long")
1193
1228
  });
1194
1229
  const pagination = ({ strapi: strapi2 }) => {
1195
1230
  const { PAGINATION_TYPE_NAME: PAGINATION_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
@@ -1210,7 +1245,8 @@ const pagination = ({ strapi: strapi2 }) => {
1210
1245
  };
1211
1246
  };
1212
1247
  const buildResponseCollectionMeta = ({ strapi: strapi2 }) => {
1213
- const { RESPONSE_COLLECTION_META_TYPE_NAME: RESPONSE_COLLECTION_META_TYPE_NAME2, PAGINATION_TYPE_NAME: PAGINATION_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1248
+ const { service: getService } = strapi2.plugin("graphql");
1249
+ const { RESPONSE_COLLECTION_META_TYPE_NAME: RESPONSE_COLLECTION_META_TYPE_NAME2, PAGINATION_TYPE_NAME: PAGINATION_TYPE_NAME2 } = getService("constants");
1214
1250
  return {
1215
1251
  /**
1216
1252
  * A shared type definition used in EntitiesResponseCollection
@@ -1220,44 +1256,38 @@ const buildResponseCollectionMeta = ({ strapi: strapi2 }) => {
1220
1256
  ResponseCollectionMeta: nexus.objectType({
1221
1257
  name: RESPONSE_COLLECTION_META_TYPE_NAME2,
1222
1258
  definition(t) {
1259
+ const { resolvePagination } = getService("builders").get("content-api");
1223
1260
  t.nonNull.field("pagination", {
1224
1261
  type: PAGINATION_TYPE_NAME2,
1225
- async resolve(parent, _childArgs, ctx) {
1226
- const { args: args2, resourceUID } = parent;
1227
- const { start, limit } = args2;
1228
- const safeLimit = Math.max(limit, 1);
1229
- const contentType2 = strapi2.getModel(resourceUID);
1230
- await utils$2.validate.contentAPI.query(args2, contentType2, {
1231
- auth: ctx?.state?.auth
1232
- });
1233
- const sanitizedQuery = await utils$2.sanitize.contentAPI.query(args2, contentType2, {
1234
- auth: ctx?.state?.auth
1235
- });
1236
- const total = await strapi2.entityService.count(resourceUID, sanitizedQuery);
1237
- const pageSize = limit === -1 ? total - start : safeLimit;
1238
- const pageCount = limit === -1 ? safeLimit : Math.ceil(total / safeLimit);
1239
- const page = limit === -1 ? safeLimit : Math.floor(start / safeLimit) + 1;
1240
- return { total, page, pageSize, pageCount };
1241
- }
1262
+ resolve: resolvePagination
1242
1263
  });
1243
1264
  }
1244
1265
  })
1245
1266
  };
1246
1267
  };
1247
- const publicationState = ({ strapi: strapi2 }) => {
1248
- const { PUBLICATION_STATE_TYPE_NAME: PUBLICATION_STATE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1268
+ const buildDeleteMutationResponse = ({ strapi: strapi2 }) => {
1269
+ const { DELETE_MUTATION_RESPONSE_TYPE_NAME: DELETE_MUTATION_RESPONSE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1270
+ return {
1271
+ DeleteMutationResponse: nexus.objectType({
1272
+ name: DELETE_MUTATION_RESPONSE_TYPE_NAME2,
1273
+ definition(t) {
1274
+ t.nonNull.id("documentId");
1275
+ }
1276
+ })
1277
+ };
1278
+ };
1279
+ const publicationStatus = ({ strapi: strapi2 }) => {
1280
+ const { PUBLICATION_STATUS_TYPE_NAME: PUBLICATION_STATUS_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1249
1281
  return {
1250
1282
  /**
1251
- * An enum type definition representing a publication state
1283
+ * An enum type definition representing a publication status
1252
1284
  * @type {NexusEnumTypeDef}
1253
1285
  */
1254
- PublicationState: nexus.enumType({
1255
- name: PUBLICATION_STATE_TYPE_NAME2,
1286
+ PublicationStatus: nexus.enumType({
1287
+ name: PUBLICATION_STATUS_TYPE_NAME2,
1256
1288
  members: {
1257
- // Published only
1258
- LIVE: "live",
1259
- // Published & draft
1260
- PREVIEW: "preview"
1289
+ DRAFT: "draft",
1290
+ PUBLISHED: "published"
1261
1291
  }
1262
1292
  })
1263
1293
  };
@@ -1314,10 +1344,11 @@ const types = (context) => () => {
1314
1344
  [KINDS2.internal]: {
1315
1345
  error: error(context),
1316
1346
  pagination: pagination(context),
1317
- responseCollectionMeta: buildResponseCollectionMeta(context)
1347
+ responseCollectionMeta: buildResponseCollectionMeta(context),
1348
+ deleteDocumentResponse: buildDeleteMutationResponse(context)
1318
1349
  },
1319
1350
  [KINDS2.enum]: {
1320
- publicationState: publicationState(context)
1351
+ publicationStatus: publicationStatus(context)
1321
1352
  },
1322
1353
  [KINDS2.filtersInput]: {
1323
1354
  ...filters$1(context)
@@ -1341,7 +1372,7 @@ const buildEnumTypeDefinition = (definition, name) => {
1341
1372
  return nexus.enumType({
1342
1373
  name,
1343
1374
  members: definition.enum.reduce(
1344
- (acc, value) => fp.set(utils$2.toRegressedEnumValue(value), value, acc),
1375
+ (acc, value) => fp.set(utils$2.strings.toRegressedEnumValue(value), value, acc),
1345
1376
  {}
1346
1377
  )
1347
1378
  });
@@ -1447,11 +1478,6 @@ const entity = ({ strapi: strapi2 }) => {
1447
1478
  }
1448
1479
  };
1449
1480
  };
1450
- function buildEntityMetaDefinition() {
1451
- }
1452
- const entityMeta = () => ({
1453
- buildEntityMetaDefinition
1454
- });
1455
1481
  const typeBuilder = (context) => {
1456
1482
  const { strapi: strapi2 } = context;
1457
1483
  const getGraphQLService = strapi2.plugin("graphql").service;
@@ -1478,7 +1504,10 @@ const typeBuilder = (context) => {
1478
1504
  attributeName,
1479
1505
  strapi: strapi2
1480
1506
  });
1481
- const args2 = getContentTypeArgs(targetComponent, { multiple: !!attribute.repeatable });
1507
+ const args2 = getContentTypeArgs(targetComponent, {
1508
+ multiple: !!attribute.repeatable,
1509
+ isNested: true
1510
+ });
1482
1511
  localBuilder.field(attributeName, { type, resolve, args: args2 });
1483
1512
  };
1484
1513
  const addDynamicZoneAttribute = (options) => {
@@ -1527,9 +1556,32 @@ const typeBuilder = (context) => {
1527
1556
  attributeName,
1528
1557
  strapi: strapi2
1529
1558
  });
1530
- const args2 = attribute.multiple ? getContentTypeArgs(fileContentType) : void 0;
1531
- const type = attribute.multiple ? naming2.getRelationResponseCollectionName(fileContentType) : naming2.getEntityResponseName(fileContentType);
1532
- builder.field(attributeName, { type, resolve, args: args2 });
1559
+ const args2 = attribute.multiple ? getContentTypeArgs(fileContentType, { isNested: true }) : void 0;
1560
+ const typeName = naming2.getTypeName(fileContentType);
1561
+ if (attribute.multiple) {
1562
+ builder.field(`${attributeName}_connection`, {
1563
+ type: naming2.getRelationResponseCollectionName(fileContentType),
1564
+ resolve,
1565
+ args: args2
1566
+ });
1567
+ builder.field(attributeName, {
1568
+ type: nexus.nonNull(nexus.list(typeName)),
1569
+ async resolve(...args22) {
1570
+ const res = await resolve(...args22);
1571
+ return res.nodes ?? [];
1572
+ },
1573
+ args: args2
1574
+ });
1575
+ } else {
1576
+ builder.field(attributeName, {
1577
+ type: typeName,
1578
+ async resolve(...args22) {
1579
+ const res = await resolve(...args22);
1580
+ return res.value;
1581
+ },
1582
+ args: args2
1583
+ });
1584
+ }
1533
1585
  };
1534
1586
  const addPolymorphicRelationalAttribute = (options) => {
1535
1587
  const { GENERIC_MORPH_TYPENAME: GENERIC_MORPH_TYPENAME2 } = getGraphQLService("constants");
@@ -1574,12 +1626,38 @@ const typeBuilder = (context) => {
1574
1626
  strapi: strapi2
1575
1627
  });
1576
1628
  const targetContentType = strapi2.getModel(attribute.target);
1577
- const type = isToManyRelation ? naming2.getRelationResponseCollectionName(targetContentType) : naming2.getEntityResponseName(targetContentType);
1578
- const args2 = isToManyRelation ? getContentTypeArgs(targetContentType) : void 0;
1579
- const resolverPath = `${naming2.getTypeName(contentType2)}.${attributeName}`;
1629
+ const typeName = naming2.getTypeName(targetContentType);
1630
+ const args2 = isToManyRelation ? getContentTypeArgs(targetContentType, { isNested: true }) : void 0;
1580
1631
  const resolverScope = `${targetContentType.uid}.find`;
1632
+ const resolverPath = `${naming2.getTypeName(contentType2)}.${attributeName}`;
1581
1633
  extension2.use({ resolversConfig: { [resolverPath]: { auth: { scope: [resolverScope] } } } });
1582
- builder.field(attributeName, { type, resolve, args: args2 });
1634
+ if (isToManyRelation) {
1635
+ builder.field(`${attributeName}_connection`, {
1636
+ type: naming2.getRelationResponseCollectionName(targetContentType),
1637
+ resolve,
1638
+ args: args2
1639
+ });
1640
+ extension2.use({
1641
+ resolversConfig: { [`${resolverPath}_connection`]: { auth: { scope: [resolverScope] } } }
1642
+ });
1643
+ builder.field(attributeName, {
1644
+ type: nexus.nonNull(nexus.list(typeName)),
1645
+ async resolve(...args22) {
1646
+ const res = await resolve(...args22);
1647
+ return res.nodes ?? [];
1648
+ },
1649
+ args: args2
1650
+ });
1651
+ } else {
1652
+ builder.field(attributeName, {
1653
+ type: typeName,
1654
+ async resolve(...args22) {
1655
+ const res = await resolve(...args22);
1656
+ return res.value;
1657
+ },
1658
+ args: args2
1659
+ });
1660
+ }
1583
1661
  };
1584
1662
  const isNotPrivate = (contentType2) => (attributeName) => {
1585
1663
  return !utils$2.contentTypes.isPrivateAttribute(contentType2, attributeName);
@@ -1614,9 +1692,29 @@ const typeBuilder = (context) => {
1614
1692
  return nexus.objectType({
1615
1693
  name,
1616
1694
  definition(t) {
1695
+ if (modelType !== "component" && isNotDisabled(contentType2)("id") && strapi2.plugin("graphql").config("v4CompatibilityMode", false)) {
1696
+ t.nonNull.id("id", {
1697
+ deprecation: "Use `documentId` instead"
1698
+ });
1699
+ }
1617
1700
  if (modelType === "component" && isNotDisabled(contentType2)("id")) {
1618
1701
  t.nonNull.id("id");
1619
1702
  }
1703
+ if (modelType !== "component" && isNotDisabled(contentType2)("documentId")) {
1704
+ t.nonNull.id("documentId");
1705
+ }
1706
+ if (strapi2.plugin("graphql").config("v4CompatibilityMode", false)) {
1707
+ t.nonNull.field("attributes", {
1708
+ deprecation: "Use root level fields instead",
1709
+ type: name,
1710
+ resolve: (parent) => parent
1711
+ });
1712
+ t.nonNull.field("data", {
1713
+ deprecation: "Use root level fields instead",
1714
+ type: name,
1715
+ resolve: (parent) => parent
1716
+ });
1717
+ }
1620
1718
  attributesKey.filter(isNotPrivate(contentType2)).filter(isNotDisabled(contentType2)).forEach((attributeName) => {
1621
1719
  const attribute = attributes2[attributeName];
1622
1720
  let builder = t;
@@ -1659,12 +1757,12 @@ const response = ({ strapi: strapi2 }) => {
1659
1757
  */
1660
1758
  buildResponseDefinition(contentType2) {
1661
1759
  const name = naming2.getEntityResponseName(contentType2);
1662
- const entityName = naming2.getEntityName(contentType2);
1760
+ const typeName = naming2.getTypeName(contentType2);
1663
1761
  return nexus.objectType({
1664
1762
  name,
1665
1763
  definition(t) {
1666
1764
  t.field("data", {
1667
- type: entityName,
1765
+ type: typeName,
1668
1766
  resolve: fp.prop("value")
1669
1767
  });
1670
1768
  }
@@ -1673,8 +1771,9 @@ const response = ({ strapi: strapi2 }) => {
1673
1771
  };
1674
1772
  };
1675
1773
  const responseCollection = ({ strapi: strapi2 }) => {
1676
- const { naming: naming2 } = strapi2.plugin("graphql").service("utils");
1677
- const { RESPONSE_COLLECTION_META_TYPE_NAME: RESPONSE_COLLECTION_META_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1774
+ const { service: getService } = strapi2.plugin("graphql");
1775
+ const { naming: naming2 } = getService("utils");
1776
+ const { RESPONSE_COLLECTION_META_TYPE_NAME: RESPONSE_COLLECTION_META_TYPE_NAME2, PAGINATION_TYPE_NAME: PAGINATION_TYPE_NAME2 } = getService("constants");
1678
1777
  return {
1679
1778
  /**
1680
1779
  * Build a type definition for a content API collection response for a given content type
@@ -1683,19 +1782,31 @@ const responseCollection = ({ strapi: strapi2 }) => {
1683
1782
  */
1684
1783
  buildResponseCollectionDefinition(contentType2) {
1685
1784
  const name = naming2.getEntityResponseCollectionName(contentType2);
1686
- const entityName = naming2.getEntityName(contentType2);
1785
+ const typeName = naming2.getTypeName(contentType2);
1786
+ const { resolvePagination } = getService("builders").get("content-api");
1687
1787
  return nexus.objectType({
1688
1788
  name,
1689
1789
  definition(t) {
1690
- t.nonNull.list.field("data", {
1691
- type: nexus.nonNull(entityName),
1790
+ t.nonNull.list.field("nodes", {
1791
+ type: nexus.nonNull(typeName),
1692
1792
  resolve: fp.pipe(fp.prop("nodes"), fp.defaultTo([]))
1693
1793
  });
1694
- t.nonNull.field("meta", {
1695
- type: RESPONSE_COLLECTION_META_TYPE_NAME2,
1696
- // Pass down the args stored in the source object
1697
- resolve: fp.prop("info")
1794
+ t.nonNull.field("pageInfo", {
1795
+ type: PAGINATION_TYPE_NAME2,
1796
+ resolve: resolvePagination
1698
1797
  });
1798
+ if (strapi2.plugin("graphql").config("v4CompatibilityMode", false)) {
1799
+ t.nonNull.list.field("data", {
1800
+ deprecation: "Use `nodes` field instead",
1801
+ type: nexus.nonNull(typeName),
1802
+ resolve: fp.pipe(fp.prop("nodes"), fp.defaultTo([]))
1803
+ });
1804
+ t.nonNull.field("meta", {
1805
+ deprecation: "Use the `pageInfo` field instead",
1806
+ type: RESPONSE_COLLECTION_META_TYPE_NAME2,
1807
+ resolve: fp.identity
1808
+ });
1809
+ }
1699
1810
  }
1700
1811
  });
1701
1812
  }
@@ -1709,14 +1820,21 @@ const relationResponseCollection = ({ strapi: strapi2 }) => {
1709
1820
  */
1710
1821
  buildRelationResponseCollectionDefinition(contentType2) {
1711
1822
  const name = naming2.getRelationResponseCollectionName(contentType2);
1712
- const entityName = naming2.getEntityName(contentType2);
1823
+ const typeName = naming2.getTypeName(contentType2);
1713
1824
  return nexus.objectType({
1714
1825
  name,
1715
1826
  definition(t) {
1716
- t.nonNull.list.field("data", {
1717
- type: nexus.nonNull(entityName),
1827
+ t.nonNull.list.field("nodes", {
1828
+ type: nexus.nonNull(typeName),
1718
1829
  resolve: fp.pipe(fp.prop("nodes"), fp.defaultTo([]))
1719
1830
  });
1831
+ if (strapi2.plugin("graphql").config("v4CompatibilityMode", false)) {
1832
+ t.nonNull.list.field("data", {
1833
+ deprecation: "Use `nodes` field instead",
1834
+ type: nexus.nonNull(typeName),
1835
+ resolve: fp.pipe(fp.prop("nodes"), fp.defaultTo([]))
1836
+ });
1837
+ }
1720
1838
  }
1721
1839
  });
1722
1840
  }
@@ -1726,16 +1844,18 @@ const createCollectionTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1726
1844
  const { service: getService } = strapi2.plugin("graphql");
1727
1845
  const { naming: naming2 } = getService("utils");
1728
1846
  const { transformArgs, getContentTypeArgs } = getService("builders").utils;
1729
- const { toEntityResponse, toEntityResponseCollection } = getService("format").returnTypes;
1847
+ const { toEntityResponseCollection } = getService("format").returnTypes;
1730
1848
  const {
1731
1849
  getFindOneQueryName,
1732
- getEntityResponseName,
1850
+ getTypeName,
1733
1851
  getFindQueryName,
1852
+ getFindConnectionQueryName,
1734
1853
  getEntityResponseCollectionName
1735
1854
  } = naming2;
1736
1855
  const buildCollectionTypeQueries = (contentType2) => {
1737
1856
  const findOneQueryName = `Query.${getFindOneQueryName(contentType2)}`;
1738
1857
  const findQueryName = `Query.${getFindQueryName(contentType2)}`;
1858
+ const findConnectionQueryName = `Query.${getFindConnectionQueryName(contentType2)}`;
1739
1859
  const extension = getService("extension");
1740
1860
  const registerAuthConfig = (action, auth) => {
1741
1861
  return extension.use({ resolversConfig: { [action]: { auth } } });
@@ -1750,6 +1870,7 @@ const createCollectionTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1750
1870
  }
1751
1871
  if (isFindEnabled) {
1752
1872
  registerAuthConfig(findQueryName, { scope: [`${contentType2.uid}.find`] });
1873
+ registerAuthConfig(findConnectionQueryName, { scope: [`${contentType2.uid}.find`] });
1753
1874
  }
1754
1875
  return nexus.extendType({
1755
1876
  type: "Query",
@@ -1758,37 +1879,64 @@ const createCollectionTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1758
1879
  addFindOneQuery(t, contentType2);
1759
1880
  }
1760
1881
  if (isFindEnabled) {
1882
+ addFindConnectionQuery(t, contentType2);
1761
1883
  addFindQuery(t, contentType2);
1762
1884
  }
1763
1885
  }
1764
1886
  });
1765
1887
  };
1766
1888
  const addFindOneQuery = (t, contentType2) => {
1767
- const { uid } = contentType2;
1768
1889
  const findOneQueryName = getFindOneQueryName(contentType2);
1769
- const responseTypeName = getEntityResponseName(contentType2);
1890
+ const typeName = getTypeName(contentType2);
1770
1891
  t.field(findOneQueryName, {
1771
- type: responseTypeName,
1892
+ type: typeName,
1893
+ extensions: {
1894
+ strapi: {
1895
+ contentType: contentType2
1896
+ }
1897
+ },
1772
1898
  args: getContentTypeArgs(contentType2, { multiple: false }),
1773
1899
  async resolve(parent, args2, ctx) {
1774
1900
  const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1775
1901
  const { findOne } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1776
- const value = findOne(parent, transformedArgs, ctx);
1777
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
1902
+ return findOne(parent, transformedArgs, ctx);
1778
1903
  }
1779
1904
  });
1780
1905
  };
1781
1906
  const addFindQuery = (t, contentType2) => {
1782
- const { uid } = contentType2;
1783
1907
  const findQueryName = getFindQueryName(contentType2);
1784
- const responseCollectionTypeName = getEntityResponseCollectionName(contentType2);
1908
+ const typeName = getTypeName(contentType2);
1785
1909
  t.field(findQueryName, {
1910
+ type: nexus.nonNull(nexus.list(typeName)),
1911
+ extensions: {
1912
+ strapi: {
1913
+ contentType: contentType2
1914
+ }
1915
+ },
1916
+ args: getContentTypeArgs(contentType2),
1917
+ async resolve(parent, args2, ctx) {
1918
+ const transformedArgs = transformArgs(args2, { contentType: contentType2, usePagination: true });
1919
+ const { findMany } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1920
+ return findMany(parent, transformedArgs, ctx);
1921
+ }
1922
+ });
1923
+ };
1924
+ const addFindConnectionQuery = (t, contentType2) => {
1925
+ const { uid } = contentType2;
1926
+ const queryName = getFindConnectionQueryName(contentType2);
1927
+ const responseCollectionTypeName = getEntityResponseCollectionName(contentType2);
1928
+ t.field(queryName, {
1786
1929
  type: responseCollectionTypeName,
1930
+ extensions: {
1931
+ strapi: {
1932
+ contentType: contentType2
1933
+ }
1934
+ },
1787
1935
  args: getContentTypeArgs(contentType2),
1788
1936
  async resolve(parent, args2, ctx) {
1789
1937
  const transformedArgs = transformArgs(args2, { contentType: contentType2, usePagination: true });
1790
- const { find } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1791
- const nodes = await find(parent, transformedArgs, ctx);
1938
+ const { findMany } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1939
+ const nodes = await findMany(parent, transformedArgs, ctx);
1792
1940
  return toEntityResponseCollection(nodes, { args: transformedArgs, resourceUID: uid });
1793
1941
  }
1794
1942
  });
@@ -1799,8 +1947,7 @@ const createSingleTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1799
1947
  const { service: getService } = strapi2.plugin("graphql");
1800
1948
  const { naming: naming2 } = getService("utils");
1801
1949
  const { transformArgs, getContentTypeArgs } = getService("builders").utils;
1802
- const { toEntityResponse } = getService("format").returnTypes;
1803
- const { getFindOneQueryName, getEntityResponseName } = naming2;
1950
+ const { getFindOneQueryName, getTypeName } = naming2;
1804
1951
  const buildSingleTypeQueries = (contentType2) => {
1805
1952
  const findQueryName = `Query.${getFindOneQueryName(contentType2)}`;
1806
1953
  const extension = getService("extension");
@@ -1824,17 +1971,20 @@ const createSingleTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1824
1971
  });
1825
1972
  };
1826
1973
  const addFindQuery = (t, contentType2) => {
1827
- const { uid } = contentType2;
1828
1974
  const findQueryName = getFindOneQueryName(contentType2);
1829
- const responseTypeName = getEntityResponseName(contentType2);
1975
+ const typeName = getTypeName(contentType2);
1830
1976
  t.field(findQueryName, {
1831
- type: responseTypeName,
1977
+ type: typeName,
1978
+ extensions: {
1979
+ strapi: {
1980
+ contentType: contentType2
1981
+ }
1982
+ },
1832
1983
  args: getContentTypeArgs(contentType2),
1833
1984
  async resolve(parent, args2, ctx) {
1834
1985
  const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1835
- const queriesResolvers2 = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1836
- const value = queriesResolvers2.find(parent, transformedArgs, ctx);
1837
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
1986
+ const { findFirst } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1987
+ return findFirst(parent, transformedArgs, ctx);
1838
1988
  }
1839
1989
  });
1840
1990
  };
@@ -1847,86 +1997,89 @@ const queries = (context) => ({
1847
1997
  const createCollectionTypeMutationsBuilder = ({ strapi: strapi2 }) => {
1848
1998
  const { service: getService } = strapi2.plugin("graphql");
1849
1999
  const { naming: naming2 } = getService("utils");
1850
- const { transformArgs } = getService("builders").utils;
1851
- const { toEntityResponse } = getService("format").returnTypes;
2000
+ const { args: args2 } = getService("internals");
1852
2001
  const {
1853
2002
  getCreateMutationTypeName,
1854
2003
  getUpdateMutationTypeName,
1855
2004
  getDeleteMutationTypeName,
1856
- getEntityResponseName,
1857
- getContentTypeInputName
2005
+ getContentTypeInputName,
2006
+ getTypeName
1858
2007
  } = naming2;
1859
2008
  const addCreateMutation = (t, contentType2) => {
1860
2009
  const { uid } = contentType2;
1861
2010
  const createMutationName = getCreateMutationTypeName(contentType2);
1862
- const responseTypeName = getEntityResponseName(contentType2);
2011
+ const typeName = getTypeName(contentType2);
1863
2012
  t.field(createMutationName, {
1864
- type: responseTypeName,
2013
+ type: typeName,
2014
+ extensions: {
2015
+ strapi: {
2016
+ contentType: contentType2
2017
+ }
2018
+ },
1865
2019
  args: {
1866
2020
  // Create payload
2021
+ status: args2.PublicationStatusArg,
1867
2022
  data: nexus.nonNull(getContentTypeInputName(contentType2))
1868
2023
  },
1869
- async resolve(parent, args2, context) {
2024
+ async resolve(parent, args22, context) {
1870
2025
  const { auth } = context.state;
1871
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1872
- const sanitizedInputData = await utils$2.sanitize.contentAPI.input(
1873
- transformedArgs.data,
1874
- contentType2,
1875
- { auth }
1876
- );
1877
- Object.assign(transformedArgs, { data: sanitizedInputData });
1878
- const { create } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
1879
- const value = await create(parent, transformedArgs);
1880
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2026
+ const sanitizedInputData = await utils$2.sanitize.contentAPI.input(args22.data, contentType2, {
2027
+ auth
2028
+ });
2029
+ return strapi2.documents(uid).create({
2030
+ ...args22,
2031
+ data: sanitizedInputData
2032
+ });
1881
2033
  }
1882
2034
  });
1883
2035
  };
1884
2036
  const addUpdateMutation = (t, contentType2) => {
1885
2037
  const { uid } = contentType2;
1886
2038
  const updateMutationName = getUpdateMutationTypeName(contentType2);
1887
- const responseTypeName = getEntityResponseName(contentType2);
2039
+ const typeName = getTypeName(contentType2);
1888
2040
  t.field(updateMutationName, {
1889
- type: responseTypeName,
2041
+ type: typeName,
2042
+ extensions: {
2043
+ strapi: {
2044
+ contentType: contentType2
2045
+ }
2046
+ },
1890
2047
  args: {
1891
- // Query args
1892
- id: nexus.nonNull("ID"),
1893
- // todo[v4]: Don't allow to filter using every unique attributes for now
1894
- // ...uniqueAttributes,
1895
- // Update payload
2048
+ documentId: nexus.nonNull(nexus.idArg()),
2049
+ status: args2.PublicationStatusArg,
1896
2050
  data: nexus.nonNull(getContentTypeInputName(contentType2))
1897
2051
  },
1898
- async resolve(parent, args2, context) {
2052
+ async resolve(parent, args22, context) {
1899
2053
  const { auth } = context.state;
1900
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1901
- const sanitizedInputData = await utils$2.sanitize.contentAPI.input(
1902
- transformedArgs.data,
1903
- contentType2,
1904
- { auth }
1905
- );
1906
- Object.assign(transformedArgs, { data: sanitizedInputData });
1907
- const { update } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
1908
- const value = await update(parent, transformedArgs);
1909
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2054
+ const { data, documentId, ...restParams } = args22;
2055
+ const sanitizedInputData = await utils$2.sanitize.contentAPI.input(data, contentType2, {
2056
+ auth
2057
+ });
2058
+ return strapi2.documents(uid).update(documentId, {
2059
+ ...restParams,
2060
+ data: sanitizedInputData
2061
+ });
1910
2062
  }
1911
2063
  });
1912
2064
  };
1913
2065
  const addDeleteMutation = (t, contentType2) => {
1914
2066
  const { uid } = contentType2;
1915
2067
  const deleteMutationName = getDeleteMutationTypeName(contentType2);
1916
- const responseTypeName = getEntityResponseName(contentType2);
2068
+ const { DELETE_MUTATION_RESPONSE_TYPE_NAME: DELETE_MUTATION_RESPONSE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1917
2069
  t.field(deleteMutationName, {
1918
- type: responseTypeName,
2070
+ type: DELETE_MUTATION_RESPONSE_TYPE_NAME2,
2071
+ extensions: {
2072
+ strapi: {
2073
+ contentType: contentType2
2074
+ }
2075
+ },
1919
2076
  args: {
1920
- // Query args
1921
- id: nexus.nonNull("ID")
1922
- // todo[v4]: Don't allow to filter using every unique attributes for now
1923
- // ...uniqueAttributes,
2077
+ documentId: nexus.nonNull(nexus.idArg())
1924
2078
  },
1925
- async resolve(parent, args2, ctx) {
1926
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1927
- const { delete: deleteResolver } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
1928
- const value = await deleteResolver(parent, args2, ctx);
1929
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2079
+ async resolve(parent, args22) {
2080
+ const { documentId } = args22;
2081
+ await strapi2.documents(uid).delete(documentId);
2082
+ return { documentId };
1930
2083
  }
1931
2084
  });
1932
2085
  };
@@ -1975,70 +2128,67 @@ const { NotFoundError } = utils$2.errors;
1975
2128
  const createSingleTypeMutationsBuilder = ({ strapi: strapi2 }) => {
1976
2129
  const { service: getService } = strapi2.plugin("graphql");
1977
2130
  const { naming: naming2 } = getService("utils");
1978
- const { transformArgs } = getService("builders").utils;
1979
- const { toEntityResponse } = getService("format").returnTypes;
2131
+ const { args: args2 } = getService("internals");
1980
2132
  const {
1981
2133
  getUpdateMutationTypeName,
1982
- getEntityResponseName,
2134
+ getTypeName,
1983
2135
  getContentTypeInputName,
1984
2136
  getDeleteMutationTypeName
1985
2137
  } = naming2;
1986
2138
  const addUpdateMutation = (t, contentType2) => {
1987
2139
  const { uid } = contentType2;
1988
2140
  const updateMutationName = getUpdateMutationTypeName(contentType2);
1989
- const responseTypeName = getEntityResponseName(contentType2);
2141
+ const typeName = getTypeName(contentType2);
1990
2142
  t.field(updateMutationName, {
1991
- type: responseTypeName,
2143
+ type: typeName,
2144
+ extensions: {
2145
+ strapi: {
2146
+ contentType: contentType2
2147
+ }
2148
+ },
1992
2149
  args: {
1993
2150
  // Update payload
2151
+ status: args2.PublicationStatusArg,
1994
2152
  data: nexus.nonNull(getContentTypeInputName(contentType2))
1995
2153
  },
1996
- async resolve(parent, args2, context) {
2154
+ async resolve(parent, args22, context) {
1997
2155
  const { auth } = context.state;
1998
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1999
- const sanitizedInputData = await utils$2.sanitize.contentAPI.input(
2000
- transformedArgs.data,
2001
- contentType2,
2002
- { auth }
2003
- );
2004
- Object.assign(transformedArgs, { data: sanitizedInputData });
2005
- const { create, update } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
2006
- await utils$2.validate.contentAPI.query(fp.omit(["data", "files"], transformedArgs), contentType2, {
2156
+ const sanitizedInputData = await utils$2.sanitize.contentAPI.input(args22.data, contentType2, {
2007
2157
  auth
2008
2158
  });
2009
- const sanitizedQuery = await utils$2.sanitize.contentAPI.query(
2010
- fp.omit(["data", "files"], transformedArgs),
2011
- contentType2,
2012
- {
2013
- auth
2014
- }
2015
- );
2016
- const entity2 = await strapi2.entityService.findMany(uid, sanitizedQuery);
2017
- const value = fp.isNil(entity2) ? create(parent, transformedArgs) : update(uid, { id: entity2.id, data: transformedArgs.data });
2018
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2159
+ const document = await strapi2.db?.query(uid).findOne();
2160
+ if (document) {
2161
+ return strapi2.documents(uid).update(document.documentId, {
2162
+ ...args22,
2163
+ data: sanitizedInputData
2164
+ });
2165
+ }
2166
+ return strapi2.documents(uid).create({
2167
+ ...args22,
2168
+ data: sanitizedInputData
2169
+ });
2019
2170
  }
2020
2171
  });
2021
2172
  };
2022
2173
  const addDeleteMutation = (t, contentType2) => {
2023
2174
  const { uid } = contentType2;
2024
2175
  const deleteMutationName = getDeleteMutationTypeName(contentType2);
2025
- const responseTypeName = getEntityResponseName(contentType2);
2176
+ const { DELETE_MUTATION_RESPONSE_TYPE_NAME: DELETE_MUTATION_RESPONSE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
2026
2177
  t.field(deleteMutationName, {
2027
- type: responseTypeName,
2178
+ type: DELETE_MUTATION_RESPONSE_TYPE_NAME2,
2179
+ extensions: {
2180
+ strapi: {
2181
+ contentType: contentType2
2182
+ }
2183
+ },
2028
2184
  args: {},
2029
- async resolve(parent, args2, ctx) {
2030
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
2031
- const { delete: deleteResolver } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
2032
- await utils$2.validate.contentAPI.query(transformedArgs, contentType2, { auth: ctx?.state?.auth });
2033
- const sanitizedQuery = await utils$2.sanitize.contentAPI.query(transformedArgs, contentType2, {
2034
- auth: ctx?.state?.auth
2035
- });
2036
- const entity2 = await strapi2.entityService.findMany(uid, sanitizedQuery);
2037
- if (!entity2) {
2038
- throw new NotFoundError("Entity not found");
2185
+ async resolve(parent, args22) {
2186
+ const document = await strapi2.db?.query(uid).findOne();
2187
+ if (!document) {
2188
+ throw new NotFoundError("Document not found");
2039
2189
  }
2040
- const value = await deleteResolver(parent, { id: entity2.id, params: transformedArgs });
2041
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2190
+ await strapi2.documents(uid).delete(document.documentId, args22);
2191
+ return document;
2042
2192
  }
2043
2193
  });
2044
2194
  };
@@ -2125,9 +2275,9 @@ const contentType = ({ strapi: strapi2 }) => {
2125
2275
  const validAttributes = Object.entries(attributes2).filter(
2126
2276
  ([attributeName]) => extension.shadowCRUD(contentType2.uid).field(attributeName).hasFiltersEnabeld()
2127
2277
  );
2128
- const isIDFilterEnabled = extension.shadowCRUD(contentType2.uid).field("id").hasFiltersEnabeld();
2278
+ const isIDFilterEnabled = extension.shadowCRUD(contentType2.uid).field("documentId").hasFiltersEnabeld();
2129
2279
  if (contentType2.kind === "collectionType" && isIDFilterEnabled) {
2130
- t.field("id", { type: getScalarFilterInputTypeName("ID") });
2280
+ t.field("documentId", { type: getScalarFilterInputTypeName("ID") });
2131
2281
  }
2132
2282
  for (const [attributeName, attribute] of validAttributes) {
2133
2283
  if (isStrapiScalar(attribute)) {
@@ -2287,12 +2437,7 @@ const associationResolvers = ({ strapi: strapi2 }) => {
2287
2437
  const sanitizedQuery = await utils$2.sanitize.contentAPI.query(transformedArgs, targetContentType, {
2288
2438
  auth
2289
2439
  });
2290
- const data = await strapi2.entityService.load(
2291
- contentTypeUID,
2292
- parent,
2293
- attributeName,
2294
- sanitizedQuery
2295
- );
2440
+ const data = await strapi2.db?.query(contentTypeUID).load(parent, attributeName, sanitizedQuery);
2296
2441
  const info = {
2297
2442
  args: sanitizedQuery,
2298
2443
  resourceUID: targetUID
@@ -2303,7 +2448,7 @@ const associationResolvers = ({ strapi: strapi2 }) => {
2303
2448
  return utils$2.sanitize.contentAPI.output(dataToSanitize, contentType2, { auth });
2304
2449
  };
2305
2450
  const unwrapData = fp.get(attributeName);
2306
- const sanitizeMorphAttribute = utils$2.pipeAsync(wrapData, sanitizeData, unwrapData);
2451
+ const sanitizeMorphAttribute = utils$2.async.pipe(wrapData, sanitizeData, unwrapData);
2307
2452
  return sanitizeMorphAttribute(data);
2308
2453
  }
2309
2454
  if (isToMany) {
@@ -2318,49 +2463,35 @@ const queriesResolvers = ({ strapi: strapi2 }) => ({
2318
2463
  buildQueriesResolvers({ contentType: contentType2 }) {
2319
2464
  const { uid } = contentType2;
2320
2465
  return {
2321
- async find(parent, args2, ctx) {
2466
+ async findMany(parent, args2, ctx) {
2322
2467
  await utils$2.validate.contentAPI.query(args2, contentType2, {
2323
2468
  auth: ctx?.state?.auth
2324
2469
  });
2325
2470
  const sanitizedQuery = await utils$2.sanitize.contentAPI.query(args2, contentType2, {
2326
2471
  auth: ctx?.state?.auth
2327
2472
  });
2328
- return strapi2.entityService.findMany(uid, sanitizedQuery);
2473
+ return strapi2.documents(uid).findMany({ status: "published", ...sanitizedQuery });
2329
2474
  },
2330
- async findOne(parent, args2, ctx) {
2475
+ async findFirst(parent, args2, ctx) {
2331
2476
  await utils$2.validate.contentAPI.query(args2, contentType2, {
2332
2477
  auth: ctx?.state?.auth
2333
2478
  });
2334
2479
  const sanitizedQuery = await utils$2.sanitize.contentAPI.query(args2, contentType2, {
2335
2480
  auth: ctx?.state?.auth
2336
2481
  });
2337
- return strapi2.entityService.findOne(uid, args2.id, fp.omit("id", sanitizedQuery));
2338
- }
2339
- };
2340
- }
2341
- });
2342
- const pickCreateArgs = fp.pick(["params", "data", "files"]);
2343
- const mutationsResolvers = ({ strapi: strapi2 }) => ({
2344
- buildMutationsResolvers({ contentType: contentType2 }) {
2345
- const { uid } = contentType2;
2346
- return {
2347
- async create(parent, args2) {
2348
- const params = pickCreateArgs(args2);
2349
- return strapi2.entityService.create(uid, params);
2350
- },
2351
- async update(parent, args2) {
2352
- const { id, data } = args2;
2353
- return strapi2.entityService.update(uid, id, { data });
2482
+ return strapi2.documents(uid).findFirst({ status: "published", ...sanitizedQuery });
2354
2483
  },
2355
- async delete(parent, args2, ctx) {
2356
- const { id, ...rest } = args2;
2357
- await utils$2.validate.contentAPI.query(rest, contentType2, {
2484
+ async findOne(parent, args2, ctx) {
2485
+ await utils$2.validate.contentAPI.query(args2, contentType2, {
2358
2486
  auth: ctx?.state?.auth
2359
2487
  });
2360
- const sanitizedQuery = await utils$2.sanitize.contentAPI.query(rest, contentType2, {
2488
+ const sanitizedQuery = await utils$2.sanitize.contentAPI.query(args2, contentType2, {
2361
2489
  auth: ctx?.state?.auth
2362
2490
  });
2363
- return strapi2.entityService.delete(uid, id, sanitizedQuery);
2491
+ return strapi2.documents(uid).findOne(args2.documentId, {
2492
+ status: "published",
2493
+ ...fp.omit(["id", "documentId"], sanitizedQuery)
2494
+ });
2364
2495
  }
2365
2496
  };
2366
2497
  }
@@ -2382,7 +2513,7 @@ const componentResolvers = ({ strapi: strapi2 }) => ({
2382
2513
  const sanitizedQuery = await utils$2.sanitize.contentAPI.query(transformedArgs, component, {
2383
2514
  auth: ctx?.state?.auth
2384
2515
  });
2385
- return strapi2.entityService.load(contentTypeUID, parent, attributeName, sanitizedQuery);
2516
+ return strapi2.db?.query(contentTypeUID).load(parent, attributeName, sanitizedQuery);
2386
2517
  };
2387
2518
  }
2388
2519
  });
@@ -2392,18 +2523,37 @@ const dynamicZoneResolvers = ({ strapi: strapi2 }) => ({
2392
2523
  attributeName
2393
2524
  }) {
2394
2525
  return async (parent) => {
2395
- return strapi2.entityService.load(contentTypeUID, parent, attributeName);
2526
+ return strapi2.db?.query(contentTypeUID).load(parent, attributeName);
2396
2527
  };
2397
2528
  }
2398
2529
  });
2530
+ const paginationResolvers = ({ strapi: strapi2 }) => ({
2531
+ async resolvePagination(parent, _, ctx) {
2532
+ const { args: args2, resourceUID } = parent.info;
2533
+ const { start, limit } = args2;
2534
+ const safeLimit = Math.max(limit, 1);
2535
+ const contentType2 = strapi2.getModel(resourceUID);
2536
+ await utils$2.validate.contentAPI.query(args2, contentType2, {
2537
+ auth: ctx?.state?.auth
2538
+ });
2539
+ const sanitizedQuery = await utils$2.sanitize.contentAPI.query(args2, contentType2, {
2540
+ auth: ctx?.state?.auth
2541
+ });
2542
+ const total = await strapi2.documents(resourceUID).count(sanitizedQuery);
2543
+ const pageSize = limit === -1 ? total - start : safeLimit;
2544
+ const pageCount = limit === -1 ? safeLimit : Math.ceil(total / safeLimit);
2545
+ const page = limit === -1 ? safeLimit : Math.floor(start / safeLimit) + 1;
2546
+ return { total, page, pageSize, pageCount };
2547
+ }
2548
+ });
2399
2549
  const resolvers = (context) => ({
2400
2550
  // Generics
2401
2551
  ...associationResolvers(context),
2402
2552
  // Builders
2403
- ...mutationsResolvers(context),
2404
2553
  ...queriesResolvers(context),
2405
2554
  ...componentResolvers(context),
2406
- ...dynamicZoneResolvers(context)
2555
+ ...dynamicZoneResolvers(context),
2556
+ ...paginationResolvers(context)
2407
2557
  });
2408
2558
  const AND_FIELD_NAME = "and";
2409
2559
  const andOperator = () => ({
@@ -2619,18 +2769,10 @@ const operators = {
2619
2769
  };
2620
2770
  const operators$1 = ({ strapi: strapi2 }) => fp.mapValues((opCtor) => opCtor({ strapi: strapi2 }), operators);
2621
2771
  const { withDefaultPagination } = utils$2.pagination;
2622
- const { hasDraftAndPublish } = utils$2.contentTypes;
2623
2772
  const utils = ({ strapi: strapi2 }) => {
2624
2773
  const { service: getService } = strapi2.plugin("graphql");
2625
2774
  return {
2626
- /**
2627
- * Get every args for a given content type
2628
- * @param {object} contentType
2629
- * @param {object} options
2630
- * @param {boolean} options.multiple
2631
- * @return {object}
2632
- */
2633
- getContentTypeArgs(contentType2, { multiple = true } = {}) {
2775
+ getContentTypeArgs(contentType2, { multiple = true, isNested = false } = {}) {
2634
2776
  const { naming: naming2 } = getService("utils");
2635
2777
  const { args: args2 } = getService("internals");
2636
2778
  const { modelType } = contentType2;
@@ -2646,22 +2788,25 @@ const utils = ({ strapi: strapi2 }) => {
2646
2788
  const { kind } = contentType2;
2647
2789
  if (kind === "collectionType") {
2648
2790
  if (!multiple) {
2649
- return { id: "ID" };
2791
+ return {
2792
+ documentId: nexus.nonNull(nexus.idArg()),
2793
+ status: args2.PublicationStatusArg
2794
+ };
2650
2795
  }
2651
2796
  const params = {
2652
2797
  filters: naming2.getFiltersInputTypeName(contentType2),
2653
2798
  pagination: args2.PaginationArg,
2654
2799
  sort: args2.SortArg
2655
2800
  };
2656
- if (hasDraftAndPublish(contentType2)) {
2657
- Object.assign(params, { publicationState: args2.PublicationStateArg });
2801
+ if (!isNested) {
2802
+ Object.assign(params, { status: args2.PublicationStatusArg });
2658
2803
  }
2659
2804
  return params;
2660
2805
  }
2661
2806
  if (kind === "singleType") {
2662
2807
  const params = {};
2663
- if (hasDraftAndPublish(contentType2)) {
2664
- Object.assign(params, { publicationState: args2.PublicationStateArg });
2808
+ if (!isNested) {
2809
+ Object.assign(params, { status: args2.PublicationStatusArg });
2665
2810
  }
2666
2811
  return params;
2667
2812
  }
@@ -2726,7 +2871,6 @@ const buildersFactories = [
2726
2871
  enums,
2727
2872
  dynamicZone,
2728
2873
  entity,
2729
- entityMeta,
2730
2874
  typeBuilder,
2731
2875
  response,
2732
2876
  responseCollection,