@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,13 +1,16 @@
1
- import { isEmpty, toUpper, snakeCase, pick, mergeWith, isArray, propOr, get, getOr, first, isFunction, isNil, prop, startsWith, difference, propEq, isDate, isObject, has, mapValues, map, upperFirst, camelCase, pipe, lowerFirst, set, omit, identity, constant, isUndefined, isString, defaultTo, entries, reduce, merge as merge$1 } from "lodash/fp";
2
- import { ForbiddenError as ForbiddenError$2, UserInputError, ApolloError, ApolloServer } from "apollo-server-koa";
3
- import { ApolloServerPluginLandingPageDisabled, ApolloServerPluginLandingPageGraphQLPlayground } from "apollo-server-core";
1
+ import { isEmpty, toUpper, snakeCase, pick, mergeWith, isArray, isObject, propOr, get, getOr, first, isFunction, isNil, prop, startsWith, difference, propEq, isDate, has, mapValues, map, upperFirst, camelCase, pipe, lowerFirst, set, omit, identity, constant, isUndefined, isString, defaultTo, entries, reduce, merge as merge$1 } from "lodash/fp";
2
+ import { ApolloServer } from "@apollo/server";
3
+ import { ApolloServerPluginLandingPageLocalDefault, ApolloServerPluginLandingPageProductionDefault } from "@apollo/server/plugin/landingPage/default";
4
+ import { koaMiddleware } from "@as-integrations/koa";
4
5
  import depthLimit from "graphql-depth-limit";
5
- import { graphqlUploadKoa, GraphQLUpload } from "graphql-upload";
6
- import { errors, policy, parseType, validate, sanitize, toRegressedEnumValue, contentTypes, pipeAsync, pagination as pagination$1 } from "@strapi/utils";
6
+ import bodyParser from "koa-bodyparser";
7
+ import cors from "@koa/cors";
8
+ import { errors, policy, parseType, strings, contentTypes, sanitize, validate, async, pagination as pagination$1 } from "@strapi/utils";
9
+ import { unwrapResolverError } from "@apollo/server/errors";
7
10
  import { GraphQLError, GraphQLObjectType, GraphQLScalarType, Kind, valueFromASTUntyped } from "graphql";
8
11
  import { pruneSchema } from "@graphql-tools/utils";
9
12
  import * as nexus from "nexus";
10
- import { unionType, makeSchema, arg, list, inputObjectType, asNexusMethod, objectType, enumType, scalarType, nonNull, extendType } from "nexus";
13
+ import { unionType, makeSchema, arg, list, inputObjectType, asNexusMethod, objectType, enumType, scalarType, nonNull, extendType, idArg } from "nexus";
11
14
  import { singular } from "pluralize";
12
15
  import { GraphQLDate, GraphQLJSON, GraphQLDateTime, GraphQLLong } from "graphql-scalars";
13
16
  const defaultConfig = {
@@ -15,7 +18,8 @@ const defaultConfig = {
15
18
  endpoint: "/graphql",
16
19
  subscriptions: false,
17
20
  maxLimit: -1,
18
- apolloServer: {}
21
+ apolloServer: {},
22
+ v4CompatibilityMode: process.env.STRAPI_GRAPHQL_V4_COMPATIBILITY_MODE ?? false
19
23
  };
20
24
  const config = {
21
25
  default: defaultConfig
@@ -25,41 +29,49 @@ const formatToCode = (name) => `STRAPI_${toUpper(snakeCase(name))}`;
25
29
  const formatErrorToExtension = (error2) => ({
26
30
  error: pick(["name", "message", "details"])(error2)
27
31
  });
28
- function formatGraphqlError(error2) {
29
- const { originalError } = error2;
32
+ function createFormattedError(formattedError, message, code, originalError) {
33
+ const options = {
34
+ ...formattedError,
35
+ extensions: {
36
+ ...formattedError.extensions,
37
+ ...formatErrorToExtension(originalError),
38
+ code
39
+ }
40
+ };
41
+ return new GraphQLError(message, options);
42
+ }
43
+ function formatGraphqlError(formattedError, error2) {
44
+ const originalError = unwrapResolverError(error2);
30
45
  if (isEmpty(originalError)) {
31
- return error2;
46
+ return formattedError;
32
47
  }
48
+ const { message = "", name = "UNKNOWN" } = originalError;
33
49
  if (originalError instanceof ForbiddenError$1 || originalError instanceof UnauthorizedError) {
34
- return new ForbiddenError$2(originalError.message, formatErrorToExtension(originalError));
50
+ return createFormattedError(formattedError, message, "FORBIDDEN", originalError);
35
51
  }
36
52
  if (originalError instanceof ValidationError$3) {
37
- return new UserInputError(originalError.message, formatErrorToExtension(originalError));
53
+ return createFormattedError(formattedError, message, "BAD_USER_INPUT", originalError);
38
54
  }
39
55
  if (originalError instanceof ApplicationError$5 || originalError instanceof HttpError) {
40
- const name = formatToCode(originalError.name);
41
- return new ApolloError(originalError.message, name, formatErrorToExtension(originalError));
56
+ const errorName = formatToCode(name);
57
+ return createFormattedError(formattedError, message, errorName, originalError);
42
58
  }
43
- if (originalError instanceof ApolloError || originalError instanceof GraphQLError) {
44
- return error2;
59
+ if (originalError instanceof GraphQLError) {
60
+ return formattedError;
45
61
  }
46
62
  strapi.log.error(originalError);
47
- return new ApolloError("Internal Server Error", "INTERNAL_SERVER_ERROR");
63
+ return createFormattedError(
64
+ new GraphQLError("Internal Server Error"),
65
+ "Internal Server Error",
66
+ "INTERNAL_SERVER_ERROR",
67
+ originalError
68
+ );
48
69
  }
49
70
  const merge = mergeWith((a, b) => {
50
71
  if (isArray(a) && isArray(b)) {
51
72
  return a.concat(b);
52
73
  }
53
74
  });
54
- const useUploadMiddleware = (strapi2, path) => {
55
- const uploadMiddleware = graphqlUploadKoa();
56
- strapi2.server.app.use((ctx, next) => {
57
- if (ctx.path === path) {
58
- return uploadMiddleware(ctx, next);
59
- }
60
- return next();
61
- });
62
- };
63
75
  async function bootstrap({ strapi: strapi2 }) {
64
76
  const schema = strapi2.plugin("graphql").service("content-api").buildSchema();
65
77
  if (isEmpty(schema)) {
@@ -68,14 +80,18 @@ async function bootstrap({ strapi: strapi2 }) {
68
80
  }
69
81
  const { config: config2 } = strapi2.plugin("graphql");
70
82
  const path = config2("endpoint");
83
+ const playgroundEnabled = !(process.env.NODE_ENV === "production" && !config2("playgroundAlways"));
84
+ let landingPage;
85
+ if (playgroundEnabled) {
86
+ landingPage = ApolloServerPluginLandingPageLocalDefault();
87
+ strapi2.log.debug("Using Apollo sandbox landing page");
88
+ } else {
89
+ landingPage = ApolloServerPluginLandingPageProductionDefault();
90
+ strapi2.log.debug("Using Apollo production landing page");
91
+ }
71
92
  const defaultServerConfig = {
72
93
  // Schema
73
94
  schema,
74
- // Initialize loaders for this request.
75
- context: ({ ctx }) => ({
76
- state: ctx.state,
77
- koaContext: ctx
78
- }),
79
95
  // Validation
80
96
  validationRules: [depthLimit(config2("depthLimit"))],
81
97
  // Errors
@@ -84,14 +100,16 @@ async function bootstrap({ strapi: strapi2 }) {
84
100
  cors: false,
85
101
  uploads: false,
86
102
  bodyParserConfig: true,
87
- plugins: [
88
- process.env.NODE_ENV === "production" && !config2("playgroundAlways") ? ApolloServerPluginLandingPageDisabled() : ApolloServerPluginLandingPageGraphQLPlayground()
89
- ],
103
+ // send 400 http status instead of 200 for input validation errors
104
+ status400ForVariableCoercionErrors: true,
105
+ plugins: [landingPage],
90
106
  cache: "bounded"
91
107
  };
92
- const serverConfig = merge(defaultServerConfig, config2("apolloServer"));
108
+ const serverConfig = merge(
109
+ defaultServerConfig,
110
+ config2("apolloServer")
111
+ );
93
112
  const server = new ApolloServer(serverConfig);
94
- useUploadMiddleware(strapi2, path);
95
113
  try {
96
114
  await server.start();
97
115
  } catch (error2) {
@@ -100,29 +118,43 @@ async function bootstrap({ strapi: strapi2 }) {
100
118
  }
101
119
  throw error2;
102
120
  }
121
+ const handler = [];
122
+ if (cors) {
123
+ handler.push(cors());
124
+ }
125
+ if (isObject(serverConfig.bodyParserConfig)) {
126
+ handler.push(bodyParser(serverConfig.bodyParserConfig));
127
+ } else if (serverConfig.bodyParserConfig) {
128
+ handler.push(bodyParser());
129
+ } else {
130
+ strapi2.log.debug("Body parser has been disabled for Apollo server");
131
+ }
132
+ handler.push((ctx, next) => {
133
+ ctx.state.route = {
134
+ info: {
135
+ // Indicate it's a content API route
136
+ type: "content-api"
137
+ }
138
+ };
139
+ if (ctx.request.method === "GET") {
140
+ return next();
141
+ }
142
+ return strapi2.auth.authenticate(ctx, next);
143
+ });
144
+ handler.push(
145
+ koaMiddleware(server, {
146
+ // Initialize loaders for this request.
147
+ context: async ({ ctx }) => ({
148
+ state: ctx.state,
149
+ koaContext: ctx
150
+ })
151
+ })
152
+ );
103
153
  strapi2.server.routes([
104
154
  {
105
155
  method: "ALL",
106
156
  path,
107
- handler: [
108
- (ctx, next) => {
109
- ctx.state.route = {
110
- info: {
111
- // Indicate it's a content API route
112
- type: "content-api"
113
- }
114
- };
115
- if (ctx.request.method === "GET")
116
- return next();
117
- return strapi2.auth.authenticate(ctx, next);
118
- },
119
- // Apollo Server
120
- server.getMiddleware({
121
- path,
122
- cors: serverConfig.cors,
123
- bodyParserConfig: serverConfig.bodyParserConfig
124
- })
125
- ],
157
+ handler,
126
158
  config: {
127
159
  auth: false
128
160
  }
@@ -433,7 +465,7 @@ const registerInternals = ({ registry, strapi: strapi2 }) => {
433
465
  registry.registerMany(Object.entries(definitions), { kind });
434
466
  }
435
467
  };
436
- const registerDynamicZonesDefinition$1 = (contentType2, {
468
+ const registerDynamicZonesDefinition = (contentType2, {
437
469
  registry,
438
470
  strapi: strapi2,
439
471
  builders: builders2
@@ -462,7 +494,7 @@ const registerDynamicZonesDefinition$1 = (contentType2, {
462
494
  registry.register(dzInputName, input, { kind: KINDS2.input, ...baseConfig });
463
495
  }
464
496
  };
465
- const registerEnumsDefinition$1 = (contentType2, {
497
+ const registerEnumsDefinition = (contentType2, {
466
498
  registry,
467
499
  strapi: strapi2,
468
500
  builders: builders2
@@ -489,7 +521,7 @@ const registerEnumsDefinition$1 = (contentType2, {
489
521
  });
490
522
  }
491
523
  };
492
- const registerInputsDefinition$1 = (contentType2, {
524
+ const registerInputsDefinition = (contentType2, {
493
525
  registry,
494
526
  strapi: strapi2,
495
527
  builders: builders2
@@ -505,7 +537,7 @@ const registerInputsDefinition$1 = (contentType2, {
505
537
  const definition = builders2.buildInputType(contentType2);
506
538
  registry.register(type, definition, { kind: KINDS2.input, contentType: contentType2 });
507
539
  };
508
- const registerFiltersDefinition$1 = (contentType2, {
540
+ const registerFiltersDefinition = (contentType2, {
509
541
  registry,
510
542
  strapi: strapi2,
511
543
  builders: builders2
@@ -517,18 +549,6 @@ const registerFiltersDefinition$1 = (contentType2, {
517
549
  const definition = builders2.buildContentTypeFilters(contentType2);
518
550
  registry.register(type, definition, { kind: KINDS2.filtersInput, contentType: contentType2 });
519
551
  };
520
- const contentType$1 = {
521
- registerDynamicZonesDefinition: registerDynamicZonesDefinition$1,
522
- registerFiltersDefinition: registerFiltersDefinition$1,
523
- registerInputsDefinition: registerInputsDefinition$1,
524
- registerEnumsDefinition: registerEnumsDefinition$1
525
- };
526
- const {
527
- registerEnumsDefinition,
528
- registerInputsDefinition,
529
- registerFiltersDefinition,
530
- registerDynamicZonesDefinition
531
- } = contentType$1;
532
552
  const contentAPI = ({ strapi: strapi2 }) => {
533
553
  const { mergeSchemas, addResolversToSchema } = require("@graphql-tools/schema");
534
554
  const { service: getGraphQLService } = strapi2.plugin("graphql");
@@ -715,7 +735,7 @@ const strapiScalarToGraphQLScalar = ({ strapi: strapi2 }) => {
715
735
  }
716
736
  };
717
737
  };
718
- const virtualScalarAttributes = ["id"];
738
+ const virtualScalarAttributes = ["id", "documentId"];
719
739
  const graphQLFiltersToStrapiQuery = ({ strapi: strapi2 }) => {
720
740
  const { service: getService } = strapi2.plugin("graphql");
721
741
  const recursivelyReplaceScalarOperators = (data) => {
@@ -929,6 +949,9 @@ const naming = ({ strapi: strapi2 }) => {
929
949
  plurality: "plural",
930
950
  firstLetterCase: "lower"
931
951
  });
952
+ const getFindConnectionQueryName = (contentType2) => {
953
+ return `${getFindQueryName(contentType2)}_connection`;
954
+ };
932
955
  const getFindOneQueryName = buildCustomTypeNameGenerator({ firstLetterCase: "lower" });
933
956
  const getCreateMutationTypeName = buildCustomTypeNameGenerator({
934
957
  prefix: "create",
@@ -966,16 +989,26 @@ const naming = ({ strapi: strapi2 }) => {
966
989
  getFindOneQueryName,
967
990
  getCreateMutationTypeName,
968
991
  getUpdateMutationTypeName,
969
- getDeleteMutationTypeName
992
+ getDeleteMutationTypeName,
993
+ getFindConnectionQueryName
994
+ };
995
+ };
996
+ const playground = (ctx) => {
997
+ return {
998
+ isEnabled() {
999
+ return !(process.env.NODE_ENV === "production" && !ctx.strapi.plugin("graphql").config("playgroundAlways"));
1000
+ }
970
1001
  };
971
1002
  };
972
1003
  const utils$1 = (context) => ({
1004
+ playground: playground(context),
973
1005
  naming: naming(context),
974
1006
  attributes: attributes(context),
975
1007
  mappers: mappers(context)
976
1008
  });
977
1009
  const PAGINATION_TYPE_NAME = "Pagination";
978
- const PUBLICATION_STATE_TYPE_NAME = "PublicationState";
1010
+ const DELETE_MUTATION_RESPONSE_TYPE_NAME = "DeleteMutationResponse";
1011
+ const PUBLICATION_STATUS_TYPE_NAME = "PublicationStatus";
979
1012
  const ERROR_TYPE_NAME = "Error";
980
1013
  const RESPONSE_COLLECTION_META_TYPE_NAME = "ResponseCollectionMeta";
981
1014
  const GRAPHQL_SCALARS = [
@@ -1096,7 +1129,8 @@ const ERROR_CODES = {
1096
1129
  const constants = () => ({
1097
1130
  PAGINATION_TYPE_NAME,
1098
1131
  RESPONSE_COLLECTION_META_TYPE_NAME,
1099
- PUBLICATION_STATE_TYPE_NAME,
1132
+ DELETE_MUTATION_RESPONSE_TYPE_NAME,
1133
+ PUBLICATION_STATUS_TYPE_NAME,
1100
1134
  GRAPHQL_SCALARS,
1101
1135
  STRAPI_SCALARS,
1102
1136
  GENERIC_MORPH_TYPENAME,
@@ -1110,11 +1144,11 @@ const SortArg = arg({
1110
1144
  type: list("String"),
1111
1145
  default: []
1112
1146
  });
1113
- const publicationState$1 = ({ strapi: strapi2 }) => {
1114
- const { PUBLICATION_STATE_TYPE_NAME: PUBLICATION_STATE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1147
+ const publicationStatus$1 = ({ strapi: strapi2 }) => {
1148
+ const { PUBLICATION_STATUS_TYPE_NAME: PUBLICATION_STATUS_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1115
1149
  return arg({
1116
- type: PUBLICATION_STATE_TYPE_NAME2,
1117
- default: "live"
1150
+ type: PUBLICATION_STATUS_TYPE_NAME2,
1151
+ default: "published"
1118
1152
  });
1119
1153
  };
1120
1154
  const PaginationInputType = inputObjectType({
@@ -1133,7 +1167,7 @@ const PaginationArg = arg({
1133
1167
  const args = (context) => ({
1134
1168
  SortArg,
1135
1169
  PaginationArg,
1136
- PublicationStateArg: publicationState$1(context)
1170
+ PublicationStatusArg: publicationStatus$1(context)
1137
1171
  });
1138
1172
  const { ValidationError: ValidationError$2 } = errors;
1139
1173
  const TimeScalar = new GraphQLScalarType({
@@ -1167,8 +1201,7 @@ const scalars = () => ({
1167
1201
  DateTime: asNexusMethod(GraphQLDateTime, "dateTime"),
1168
1202
  Time: asNexusMethod(TimeScalar, "time"),
1169
1203
  Date: asNexusMethod(GraphQLDate, "date"),
1170
- Long: asNexusMethod(GraphQLLong, "long"),
1171
- Upload: asNexusMethod(GraphQLUpload, "upload")
1204
+ Long: asNexusMethod(GraphQLLong, "long")
1172
1205
  });
1173
1206
  const pagination = ({ strapi: strapi2 }) => {
1174
1207
  const { PAGINATION_TYPE_NAME: PAGINATION_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
@@ -1189,7 +1222,8 @@ const pagination = ({ strapi: strapi2 }) => {
1189
1222
  };
1190
1223
  };
1191
1224
  const buildResponseCollectionMeta = ({ strapi: strapi2 }) => {
1192
- const { RESPONSE_COLLECTION_META_TYPE_NAME: RESPONSE_COLLECTION_META_TYPE_NAME2, PAGINATION_TYPE_NAME: PAGINATION_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1225
+ const { service: getService } = strapi2.plugin("graphql");
1226
+ const { RESPONSE_COLLECTION_META_TYPE_NAME: RESPONSE_COLLECTION_META_TYPE_NAME2, PAGINATION_TYPE_NAME: PAGINATION_TYPE_NAME2 } = getService("constants");
1193
1227
  return {
1194
1228
  /**
1195
1229
  * A shared type definition used in EntitiesResponseCollection
@@ -1199,44 +1233,38 @@ const buildResponseCollectionMeta = ({ strapi: strapi2 }) => {
1199
1233
  ResponseCollectionMeta: objectType({
1200
1234
  name: RESPONSE_COLLECTION_META_TYPE_NAME2,
1201
1235
  definition(t) {
1236
+ const { resolvePagination } = getService("builders").get("content-api");
1202
1237
  t.nonNull.field("pagination", {
1203
1238
  type: PAGINATION_TYPE_NAME2,
1204
- async resolve(parent, _childArgs, ctx) {
1205
- const { args: args2, resourceUID } = parent;
1206
- const { start, limit } = args2;
1207
- const safeLimit = Math.max(limit, 1);
1208
- const contentType2 = strapi2.getModel(resourceUID);
1209
- await validate.contentAPI.query(args2, contentType2, {
1210
- auth: ctx?.state?.auth
1211
- });
1212
- const sanitizedQuery = await sanitize.contentAPI.query(args2, contentType2, {
1213
- auth: ctx?.state?.auth
1214
- });
1215
- const total = await strapi2.entityService.count(resourceUID, sanitizedQuery);
1216
- const pageSize = limit === -1 ? total - start : safeLimit;
1217
- const pageCount = limit === -1 ? safeLimit : Math.ceil(total / safeLimit);
1218
- const page = limit === -1 ? safeLimit : Math.floor(start / safeLimit) + 1;
1219
- return { total, page, pageSize, pageCount };
1220
- }
1239
+ resolve: resolvePagination
1221
1240
  });
1222
1241
  }
1223
1242
  })
1224
1243
  };
1225
1244
  };
1226
- const publicationState = ({ strapi: strapi2 }) => {
1227
- const { PUBLICATION_STATE_TYPE_NAME: PUBLICATION_STATE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1245
+ const buildDeleteMutationResponse = ({ strapi: strapi2 }) => {
1246
+ const { DELETE_MUTATION_RESPONSE_TYPE_NAME: DELETE_MUTATION_RESPONSE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1247
+ return {
1248
+ DeleteMutationResponse: objectType({
1249
+ name: DELETE_MUTATION_RESPONSE_TYPE_NAME2,
1250
+ definition(t) {
1251
+ t.nonNull.id("documentId");
1252
+ }
1253
+ })
1254
+ };
1255
+ };
1256
+ const publicationStatus = ({ strapi: strapi2 }) => {
1257
+ const { PUBLICATION_STATUS_TYPE_NAME: PUBLICATION_STATUS_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1228
1258
  return {
1229
1259
  /**
1230
- * An enum type definition representing a publication state
1260
+ * An enum type definition representing a publication status
1231
1261
  * @type {NexusEnumTypeDef}
1232
1262
  */
1233
- PublicationState: enumType({
1234
- name: PUBLICATION_STATE_TYPE_NAME2,
1263
+ PublicationStatus: enumType({
1264
+ name: PUBLICATION_STATUS_TYPE_NAME2,
1235
1265
  members: {
1236
- // Published only
1237
- LIVE: "live",
1238
- // Published & draft
1239
- PREVIEW: "preview"
1266
+ DRAFT: "draft",
1267
+ PUBLISHED: "published"
1240
1268
  }
1241
1269
  })
1242
1270
  };
@@ -1293,10 +1321,11 @@ const types = (context) => () => {
1293
1321
  [KINDS2.internal]: {
1294
1322
  error: error(context),
1295
1323
  pagination: pagination(context),
1296
- responseCollectionMeta: buildResponseCollectionMeta(context)
1324
+ responseCollectionMeta: buildResponseCollectionMeta(context),
1325
+ deleteDocumentResponse: buildDeleteMutationResponse(context)
1297
1326
  },
1298
1327
  [KINDS2.enum]: {
1299
- publicationState: publicationState(context)
1328
+ publicationStatus: publicationStatus(context)
1300
1329
  },
1301
1330
  [KINDS2.filtersInput]: {
1302
1331
  ...filters$1(context)
@@ -1320,7 +1349,7 @@ const buildEnumTypeDefinition = (definition, name) => {
1320
1349
  return enumType({
1321
1350
  name,
1322
1351
  members: definition.enum.reduce(
1323
- (acc, value) => set(toRegressedEnumValue(value), value, acc),
1352
+ (acc, value) => set(strings.toRegressedEnumValue(value), value, acc),
1324
1353
  {}
1325
1354
  )
1326
1355
  });
@@ -1426,11 +1455,6 @@ const entity = ({ strapi: strapi2 }) => {
1426
1455
  }
1427
1456
  };
1428
1457
  };
1429
- function buildEntityMetaDefinition() {
1430
- }
1431
- const entityMeta = () => ({
1432
- buildEntityMetaDefinition
1433
- });
1434
1458
  const typeBuilder = (context) => {
1435
1459
  const { strapi: strapi2 } = context;
1436
1460
  const getGraphQLService = strapi2.plugin("graphql").service;
@@ -1457,7 +1481,10 @@ const typeBuilder = (context) => {
1457
1481
  attributeName,
1458
1482
  strapi: strapi2
1459
1483
  });
1460
- const args2 = getContentTypeArgs(targetComponent, { multiple: !!attribute.repeatable });
1484
+ const args2 = getContentTypeArgs(targetComponent, {
1485
+ multiple: !!attribute.repeatable,
1486
+ isNested: true
1487
+ });
1461
1488
  localBuilder.field(attributeName, { type, resolve, args: args2 });
1462
1489
  };
1463
1490
  const addDynamicZoneAttribute = (options) => {
@@ -1506,9 +1533,32 @@ const typeBuilder = (context) => {
1506
1533
  attributeName,
1507
1534
  strapi: strapi2
1508
1535
  });
1509
- const args2 = attribute.multiple ? getContentTypeArgs(fileContentType) : void 0;
1510
- const type = attribute.multiple ? naming2.getRelationResponseCollectionName(fileContentType) : naming2.getEntityResponseName(fileContentType);
1511
- builder.field(attributeName, { type, resolve, args: args2 });
1536
+ const args2 = attribute.multiple ? getContentTypeArgs(fileContentType, { isNested: true }) : void 0;
1537
+ const typeName = naming2.getTypeName(fileContentType);
1538
+ if (attribute.multiple) {
1539
+ builder.field(`${attributeName}_connection`, {
1540
+ type: naming2.getRelationResponseCollectionName(fileContentType),
1541
+ resolve,
1542
+ args: args2
1543
+ });
1544
+ builder.field(attributeName, {
1545
+ type: nonNull(list(typeName)),
1546
+ async resolve(...args22) {
1547
+ const res = await resolve(...args22);
1548
+ return res.nodes ?? [];
1549
+ },
1550
+ args: args2
1551
+ });
1552
+ } else {
1553
+ builder.field(attributeName, {
1554
+ type: typeName,
1555
+ async resolve(...args22) {
1556
+ const res = await resolve(...args22);
1557
+ return res.value;
1558
+ },
1559
+ args: args2
1560
+ });
1561
+ }
1512
1562
  };
1513
1563
  const addPolymorphicRelationalAttribute = (options) => {
1514
1564
  const { GENERIC_MORPH_TYPENAME: GENERIC_MORPH_TYPENAME2 } = getGraphQLService("constants");
@@ -1553,12 +1603,38 @@ const typeBuilder = (context) => {
1553
1603
  strapi: strapi2
1554
1604
  });
1555
1605
  const targetContentType = strapi2.getModel(attribute.target);
1556
- const type = isToManyRelation ? naming2.getRelationResponseCollectionName(targetContentType) : naming2.getEntityResponseName(targetContentType);
1557
- const args2 = isToManyRelation ? getContentTypeArgs(targetContentType) : void 0;
1558
- const resolverPath = `${naming2.getTypeName(contentType2)}.${attributeName}`;
1606
+ const typeName = naming2.getTypeName(targetContentType);
1607
+ const args2 = isToManyRelation ? getContentTypeArgs(targetContentType, { isNested: true }) : void 0;
1559
1608
  const resolverScope = `${targetContentType.uid}.find`;
1609
+ const resolverPath = `${naming2.getTypeName(contentType2)}.${attributeName}`;
1560
1610
  extension2.use({ resolversConfig: { [resolverPath]: { auth: { scope: [resolverScope] } } } });
1561
- builder.field(attributeName, { type, resolve, args: args2 });
1611
+ if (isToManyRelation) {
1612
+ builder.field(`${attributeName}_connection`, {
1613
+ type: naming2.getRelationResponseCollectionName(targetContentType),
1614
+ resolve,
1615
+ args: args2
1616
+ });
1617
+ extension2.use({
1618
+ resolversConfig: { [`${resolverPath}_connection`]: { auth: { scope: [resolverScope] } } }
1619
+ });
1620
+ builder.field(attributeName, {
1621
+ type: nonNull(list(typeName)),
1622
+ async resolve(...args22) {
1623
+ const res = await resolve(...args22);
1624
+ return res.nodes ?? [];
1625
+ },
1626
+ args: args2
1627
+ });
1628
+ } else {
1629
+ builder.field(attributeName, {
1630
+ type: typeName,
1631
+ async resolve(...args22) {
1632
+ const res = await resolve(...args22);
1633
+ return res.value;
1634
+ },
1635
+ args: args2
1636
+ });
1637
+ }
1562
1638
  };
1563
1639
  const isNotPrivate = (contentType2) => (attributeName) => {
1564
1640
  return !contentTypes.isPrivateAttribute(contentType2, attributeName);
@@ -1593,9 +1669,29 @@ const typeBuilder = (context) => {
1593
1669
  return objectType({
1594
1670
  name,
1595
1671
  definition(t) {
1672
+ if (modelType !== "component" && isNotDisabled(contentType2)("id") && strapi2.plugin("graphql").config("v4CompatibilityMode", false)) {
1673
+ t.nonNull.id("id", {
1674
+ deprecation: "Use `documentId` instead"
1675
+ });
1676
+ }
1596
1677
  if (modelType === "component" && isNotDisabled(contentType2)("id")) {
1597
1678
  t.nonNull.id("id");
1598
1679
  }
1680
+ if (modelType !== "component" && isNotDisabled(contentType2)("documentId")) {
1681
+ t.nonNull.id("documentId");
1682
+ }
1683
+ if (strapi2.plugin("graphql").config("v4CompatibilityMode", false)) {
1684
+ t.nonNull.field("attributes", {
1685
+ deprecation: "Use root level fields instead",
1686
+ type: name,
1687
+ resolve: (parent) => parent
1688
+ });
1689
+ t.nonNull.field("data", {
1690
+ deprecation: "Use root level fields instead",
1691
+ type: name,
1692
+ resolve: (parent) => parent
1693
+ });
1694
+ }
1599
1695
  attributesKey.filter(isNotPrivate(contentType2)).filter(isNotDisabled(contentType2)).forEach((attributeName) => {
1600
1696
  const attribute = attributes2[attributeName];
1601
1697
  let builder = t;
@@ -1638,12 +1734,12 @@ const response = ({ strapi: strapi2 }) => {
1638
1734
  */
1639
1735
  buildResponseDefinition(contentType2) {
1640
1736
  const name = naming2.getEntityResponseName(contentType2);
1641
- const entityName = naming2.getEntityName(contentType2);
1737
+ const typeName = naming2.getTypeName(contentType2);
1642
1738
  return objectType({
1643
1739
  name,
1644
1740
  definition(t) {
1645
1741
  t.field("data", {
1646
- type: entityName,
1742
+ type: typeName,
1647
1743
  resolve: prop("value")
1648
1744
  });
1649
1745
  }
@@ -1652,8 +1748,9 @@ const response = ({ strapi: strapi2 }) => {
1652
1748
  };
1653
1749
  };
1654
1750
  const responseCollection = ({ strapi: strapi2 }) => {
1655
- const { naming: naming2 } = strapi2.plugin("graphql").service("utils");
1656
- const { RESPONSE_COLLECTION_META_TYPE_NAME: RESPONSE_COLLECTION_META_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1751
+ const { service: getService } = strapi2.plugin("graphql");
1752
+ const { naming: naming2 } = getService("utils");
1753
+ const { RESPONSE_COLLECTION_META_TYPE_NAME: RESPONSE_COLLECTION_META_TYPE_NAME2, PAGINATION_TYPE_NAME: PAGINATION_TYPE_NAME2 } = getService("constants");
1657
1754
  return {
1658
1755
  /**
1659
1756
  * Build a type definition for a content API collection response for a given content type
@@ -1662,19 +1759,31 @@ const responseCollection = ({ strapi: strapi2 }) => {
1662
1759
  */
1663
1760
  buildResponseCollectionDefinition(contentType2) {
1664
1761
  const name = naming2.getEntityResponseCollectionName(contentType2);
1665
- const entityName = naming2.getEntityName(contentType2);
1762
+ const typeName = naming2.getTypeName(contentType2);
1763
+ const { resolvePagination } = getService("builders").get("content-api");
1666
1764
  return objectType({
1667
1765
  name,
1668
1766
  definition(t) {
1669
- t.nonNull.list.field("data", {
1670
- type: nonNull(entityName),
1767
+ t.nonNull.list.field("nodes", {
1768
+ type: nonNull(typeName),
1671
1769
  resolve: pipe(prop("nodes"), defaultTo([]))
1672
1770
  });
1673
- t.nonNull.field("meta", {
1674
- type: RESPONSE_COLLECTION_META_TYPE_NAME2,
1675
- // Pass down the args stored in the source object
1676
- resolve: prop("info")
1771
+ t.nonNull.field("pageInfo", {
1772
+ type: PAGINATION_TYPE_NAME2,
1773
+ resolve: resolvePagination
1677
1774
  });
1775
+ if (strapi2.plugin("graphql").config("v4CompatibilityMode", false)) {
1776
+ t.nonNull.list.field("data", {
1777
+ deprecation: "Use `nodes` field instead",
1778
+ type: nonNull(typeName),
1779
+ resolve: pipe(prop("nodes"), defaultTo([]))
1780
+ });
1781
+ t.nonNull.field("meta", {
1782
+ deprecation: "Use the `pageInfo` field instead",
1783
+ type: RESPONSE_COLLECTION_META_TYPE_NAME2,
1784
+ resolve: identity
1785
+ });
1786
+ }
1678
1787
  }
1679
1788
  });
1680
1789
  }
@@ -1688,14 +1797,21 @@ const relationResponseCollection = ({ strapi: strapi2 }) => {
1688
1797
  */
1689
1798
  buildRelationResponseCollectionDefinition(contentType2) {
1690
1799
  const name = naming2.getRelationResponseCollectionName(contentType2);
1691
- const entityName = naming2.getEntityName(contentType2);
1800
+ const typeName = naming2.getTypeName(contentType2);
1692
1801
  return objectType({
1693
1802
  name,
1694
1803
  definition(t) {
1695
- t.nonNull.list.field("data", {
1696
- type: nonNull(entityName),
1804
+ t.nonNull.list.field("nodes", {
1805
+ type: nonNull(typeName),
1697
1806
  resolve: pipe(prop("nodes"), defaultTo([]))
1698
1807
  });
1808
+ if (strapi2.plugin("graphql").config("v4CompatibilityMode", false)) {
1809
+ t.nonNull.list.field("data", {
1810
+ deprecation: "Use `nodes` field instead",
1811
+ type: nonNull(typeName),
1812
+ resolve: pipe(prop("nodes"), defaultTo([]))
1813
+ });
1814
+ }
1699
1815
  }
1700
1816
  });
1701
1817
  }
@@ -1705,16 +1821,18 @@ const createCollectionTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1705
1821
  const { service: getService } = strapi2.plugin("graphql");
1706
1822
  const { naming: naming2 } = getService("utils");
1707
1823
  const { transformArgs, getContentTypeArgs } = getService("builders").utils;
1708
- const { toEntityResponse, toEntityResponseCollection } = getService("format").returnTypes;
1824
+ const { toEntityResponseCollection } = getService("format").returnTypes;
1709
1825
  const {
1710
1826
  getFindOneQueryName,
1711
- getEntityResponseName,
1827
+ getTypeName,
1712
1828
  getFindQueryName,
1829
+ getFindConnectionQueryName,
1713
1830
  getEntityResponseCollectionName
1714
1831
  } = naming2;
1715
1832
  const buildCollectionTypeQueries = (contentType2) => {
1716
1833
  const findOneQueryName = `Query.${getFindOneQueryName(contentType2)}`;
1717
1834
  const findQueryName = `Query.${getFindQueryName(contentType2)}`;
1835
+ const findConnectionQueryName = `Query.${getFindConnectionQueryName(contentType2)}`;
1718
1836
  const extension = getService("extension");
1719
1837
  const registerAuthConfig = (action, auth) => {
1720
1838
  return extension.use({ resolversConfig: { [action]: { auth } } });
@@ -1729,6 +1847,7 @@ const createCollectionTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1729
1847
  }
1730
1848
  if (isFindEnabled) {
1731
1849
  registerAuthConfig(findQueryName, { scope: [`${contentType2.uid}.find`] });
1850
+ registerAuthConfig(findConnectionQueryName, { scope: [`${contentType2.uid}.find`] });
1732
1851
  }
1733
1852
  return extendType({
1734
1853
  type: "Query",
@@ -1737,37 +1856,64 @@ const createCollectionTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1737
1856
  addFindOneQuery(t, contentType2);
1738
1857
  }
1739
1858
  if (isFindEnabled) {
1859
+ addFindConnectionQuery(t, contentType2);
1740
1860
  addFindQuery(t, contentType2);
1741
1861
  }
1742
1862
  }
1743
1863
  });
1744
1864
  };
1745
1865
  const addFindOneQuery = (t, contentType2) => {
1746
- const { uid } = contentType2;
1747
1866
  const findOneQueryName = getFindOneQueryName(contentType2);
1748
- const responseTypeName = getEntityResponseName(contentType2);
1867
+ const typeName = getTypeName(contentType2);
1749
1868
  t.field(findOneQueryName, {
1750
- type: responseTypeName,
1869
+ type: typeName,
1870
+ extensions: {
1871
+ strapi: {
1872
+ contentType: contentType2
1873
+ }
1874
+ },
1751
1875
  args: getContentTypeArgs(contentType2, { multiple: false }),
1752
1876
  async resolve(parent, args2, ctx) {
1753
1877
  const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1754
1878
  const { findOne } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1755
- const value = findOne(parent, transformedArgs, ctx);
1756
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
1879
+ return findOne(parent, transformedArgs, ctx);
1757
1880
  }
1758
1881
  });
1759
1882
  };
1760
1883
  const addFindQuery = (t, contentType2) => {
1761
- const { uid } = contentType2;
1762
1884
  const findQueryName = getFindQueryName(contentType2);
1763
- const responseCollectionTypeName = getEntityResponseCollectionName(contentType2);
1885
+ const typeName = getTypeName(contentType2);
1764
1886
  t.field(findQueryName, {
1887
+ type: nonNull(list(typeName)),
1888
+ extensions: {
1889
+ strapi: {
1890
+ contentType: contentType2
1891
+ }
1892
+ },
1893
+ args: getContentTypeArgs(contentType2),
1894
+ async resolve(parent, args2, ctx) {
1895
+ const transformedArgs = transformArgs(args2, { contentType: contentType2, usePagination: true });
1896
+ const { findMany } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1897
+ return findMany(parent, transformedArgs, ctx);
1898
+ }
1899
+ });
1900
+ };
1901
+ const addFindConnectionQuery = (t, contentType2) => {
1902
+ const { uid } = contentType2;
1903
+ const queryName = getFindConnectionQueryName(contentType2);
1904
+ const responseCollectionTypeName = getEntityResponseCollectionName(contentType2);
1905
+ t.field(queryName, {
1765
1906
  type: responseCollectionTypeName,
1907
+ extensions: {
1908
+ strapi: {
1909
+ contentType: contentType2
1910
+ }
1911
+ },
1766
1912
  args: getContentTypeArgs(contentType2),
1767
1913
  async resolve(parent, args2, ctx) {
1768
1914
  const transformedArgs = transformArgs(args2, { contentType: contentType2, usePagination: true });
1769
- const { find } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1770
- const nodes = await find(parent, transformedArgs, ctx);
1915
+ const { findMany } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1916
+ const nodes = await findMany(parent, transformedArgs, ctx);
1771
1917
  return toEntityResponseCollection(nodes, { args: transformedArgs, resourceUID: uid });
1772
1918
  }
1773
1919
  });
@@ -1778,8 +1924,7 @@ const createSingleTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1778
1924
  const { service: getService } = strapi2.plugin("graphql");
1779
1925
  const { naming: naming2 } = getService("utils");
1780
1926
  const { transformArgs, getContentTypeArgs } = getService("builders").utils;
1781
- const { toEntityResponse } = getService("format").returnTypes;
1782
- const { getFindOneQueryName, getEntityResponseName } = naming2;
1927
+ const { getFindOneQueryName, getTypeName } = naming2;
1783
1928
  const buildSingleTypeQueries = (contentType2) => {
1784
1929
  const findQueryName = `Query.${getFindOneQueryName(contentType2)}`;
1785
1930
  const extension = getService("extension");
@@ -1803,17 +1948,20 @@ const createSingleTypeQueriesBuilder = ({ strapi: strapi2 }) => {
1803
1948
  });
1804
1949
  };
1805
1950
  const addFindQuery = (t, contentType2) => {
1806
- const { uid } = contentType2;
1807
1951
  const findQueryName = getFindOneQueryName(contentType2);
1808
- const responseTypeName = getEntityResponseName(contentType2);
1952
+ const typeName = getTypeName(contentType2);
1809
1953
  t.field(findQueryName, {
1810
- type: responseTypeName,
1954
+ type: typeName,
1955
+ extensions: {
1956
+ strapi: {
1957
+ contentType: contentType2
1958
+ }
1959
+ },
1811
1960
  args: getContentTypeArgs(contentType2),
1812
1961
  async resolve(parent, args2, ctx) {
1813
1962
  const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1814
- const queriesResolvers2 = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1815
- const value = queriesResolvers2.find(parent, transformedArgs, ctx);
1816
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
1963
+ const { findFirst } = getService("builders").get("content-api").buildQueriesResolvers({ contentType: contentType2 });
1964
+ return findFirst(parent, transformedArgs, ctx);
1817
1965
  }
1818
1966
  });
1819
1967
  };
@@ -1826,86 +1974,89 @@ const queries = (context) => ({
1826
1974
  const createCollectionTypeMutationsBuilder = ({ strapi: strapi2 }) => {
1827
1975
  const { service: getService } = strapi2.plugin("graphql");
1828
1976
  const { naming: naming2 } = getService("utils");
1829
- const { transformArgs } = getService("builders").utils;
1830
- const { toEntityResponse } = getService("format").returnTypes;
1977
+ const { args: args2 } = getService("internals");
1831
1978
  const {
1832
1979
  getCreateMutationTypeName,
1833
1980
  getUpdateMutationTypeName,
1834
1981
  getDeleteMutationTypeName,
1835
- getEntityResponseName,
1836
- getContentTypeInputName
1982
+ getContentTypeInputName,
1983
+ getTypeName
1837
1984
  } = naming2;
1838
1985
  const addCreateMutation = (t, contentType2) => {
1839
1986
  const { uid } = contentType2;
1840
1987
  const createMutationName = getCreateMutationTypeName(contentType2);
1841
- const responseTypeName = getEntityResponseName(contentType2);
1988
+ const typeName = getTypeName(contentType2);
1842
1989
  t.field(createMutationName, {
1843
- type: responseTypeName,
1990
+ type: typeName,
1991
+ extensions: {
1992
+ strapi: {
1993
+ contentType: contentType2
1994
+ }
1995
+ },
1844
1996
  args: {
1845
1997
  // Create payload
1998
+ status: args2.PublicationStatusArg,
1846
1999
  data: nonNull(getContentTypeInputName(contentType2))
1847
2000
  },
1848
- async resolve(parent, args2, context) {
2001
+ async resolve(parent, args22, context) {
1849
2002
  const { auth } = context.state;
1850
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1851
- const sanitizedInputData = await sanitize.contentAPI.input(
1852
- transformedArgs.data,
1853
- contentType2,
1854
- { auth }
1855
- );
1856
- Object.assign(transformedArgs, { data: sanitizedInputData });
1857
- const { create } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
1858
- const value = await create(parent, transformedArgs);
1859
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2003
+ const sanitizedInputData = await sanitize.contentAPI.input(args22.data, contentType2, {
2004
+ auth
2005
+ });
2006
+ return strapi2.documents(uid).create({
2007
+ ...args22,
2008
+ data: sanitizedInputData
2009
+ });
1860
2010
  }
1861
2011
  });
1862
2012
  };
1863
2013
  const addUpdateMutation = (t, contentType2) => {
1864
2014
  const { uid } = contentType2;
1865
2015
  const updateMutationName = getUpdateMutationTypeName(contentType2);
1866
- const responseTypeName = getEntityResponseName(contentType2);
2016
+ const typeName = getTypeName(contentType2);
1867
2017
  t.field(updateMutationName, {
1868
- type: responseTypeName,
2018
+ type: typeName,
2019
+ extensions: {
2020
+ strapi: {
2021
+ contentType: contentType2
2022
+ }
2023
+ },
1869
2024
  args: {
1870
- // Query args
1871
- id: nonNull("ID"),
1872
- // todo[v4]: Don't allow to filter using every unique attributes for now
1873
- // ...uniqueAttributes,
1874
- // Update payload
2025
+ documentId: nonNull(idArg()),
2026
+ status: args2.PublicationStatusArg,
1875
2027
  data: nonNull(getContentTypeInputName(contentType2))
1876
2028
  },
1877
- async resolve(parent, args2, context) {
2029
+ async resolve(parent, args22, context) {
1878
2030
  const { auth } = context.state;
1879
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1880
- const sanitizedInputData = await sanitize.contentAPI.input(
1881
- transformedArgs.data,
1882
- contentType2,
1883
- { auth }
1884
- );
1885
- Object.assign(transformedArgs, { data: sanitizedInputData });
1886
- const { update } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
1887
- const value = await update(parent, transformedArgs);
1888
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2031
+ const { data, documentId, ...restParams } = args22;
2032
+ const sanitizedInputData = await sanitize.contentAPI.input(data, contentType2, {
2033
+ auth
2034
+ });
2035
+ return strapi2.documents(uid).update(documentId, {
2036
+ ...restParams,
2037
+ data: sanitizedInputData
2038
+ });
1889
2039
  }
1890
2040
  });
1891
2041
  };
1892
2042
  const addDeleteMutation = (t, contentType2) => {
1893
2043
  const { uid } = contentType2;
1894
2044
  const deleteMutationName = getDeleteMutationTypeName(contentType2);
1895
- const responseTypeName = getEntityResponseName(contentType2);
2045
+ const { DELETE_MUTATION_RESPONSE_TYPE_NAME: DELETE_MUTATION_RESPONSE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
1896
2046
  t.field(deleteMutationName, {
1897
- type: responseTypeName,
2047
+ type: DELETE_MUTATION_RESPONSE_TYPE_NAME2,
2048
+ extensions: {
2049
+ strapi: {
2050
+ contentType: contentType2
2051
+ }
2052
+ },
1898
2053
  args: {
1899
- // Query args
1900
- id: nonNull("ID")
1901
- // todo[v4]: Don't allow to filter using every unique attributes for now
1902
- // ...uniqueAttributes,
2054
+ documentId: nonNull(idArg())
1903
2055
  },
1904
- async resolve(parent, args2, ctx) {
1905
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1906
- const { delete: deleteResolver } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
1907
- const value = await deleteResolver(parent, args2, ctx);
1908
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2056
+ async resolve(parent, args22) {
2057
+ const { documentId } = args22;
2058
+ await strapi2.documents(uid).delete(documentId);
2059
+ return { documentId };
1909
2060
  }
1910
2061
  });
1911
2062
  };
@@ -1954,70 +2105,67 @@ const { NotFoundError } = errors;
1954
2105
  const createSingleTypeMutationsBuilder = ({ strapi: strapi2 }) => {
1955
2106
  const { service: getService } = strapi2.plugin("graphql");
1956
2107
  const { naming: naming2 } = getService("utils");
1957
- const { transformArgs } = getService("builders").utils;
1958
- const { toEntityResponse } = getService("format").returnTypes;
2108
+ const { args: args2 } = getService("internals");
1959
2109
  const {
1960
2110
  getUpdateMutationTypeName,
1961
- getEntityResponseName,
2111
+ getTypeName,
1962
2112
  getContentTypeInputName,
1963
2113
  getDeleteMutationTypeName
1964
2114
  } = naming2;
1965
2115
  const addUpdateMutation = (t, contentType2) => {
1966
2116
  const { uid } = contentType2;
1967
2117
  const updateMutationName = getUpdateMutationTypeName(contentType2);
1968
- const responseTypeName = getEntityResponseName(contentType2);
2118
+ const typeName = getTypeName(contentType2);
1969
2119
  t.field(updateMutationName, {
1970
- type: responseTypeName,
2120
+ type: typeName,
2121
+ extensions: {
2122
+ strapi: {
2123
+ contentType: contentType2
2124
+ }
2125
+ },
1971
2126
  args: {
1972
2127
  // Update payload
2128
+ status: args2.PublicationStatusArg,
1973
2129
  data: nonNull(getContentTypeInputName(contentType2))
1974
2130
  },
1975
- async resolve(parent, args2, context) {
2131
+ async resolve(parent, args22, context) {
1976
2132
  const { auth } = context.state;
1977
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
1978
- const sanitizedInputData = await sanitize.contentAPI.input(
1979
- transformedArgs.data,
1980
- contentType2,
1981
- { auth }
1982
- );
1983
- Object.assign(transformedArgs, { data: sanitizedInputData });
1984
- const { create, update } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
1985
- await validate.contentAPI.query(omit(["data", "files"], transformedArgs), contentType2, {
2133
+ const sanitizedInputData = await sanitize.contentAPI.input(args22.data, contentType2, {
1986
2134
  auth
1987
2135
  });
1988
- const sanitizedQuery = await sanitize.contentAPI.query(
1989
- omit(["data", "files"], transformedArgs),
1990
- contentType2,
1991
- {
1992
- auth
1993
- }
1994
- );
1995
- const entity2 = await strapi2.entityService.findMany(uid, sanitizedQuery);
1996
- const value = isNil(entity2) ? create(parent, transformedArgs) : update(uid, { id: entity2.id, data: transformedArgs.data });
1997
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2136
+ const document = await strapi2.db?.query(uid).findOne();
2137
+ if (document) {
2138
+ return strapi2.documents(uid).update(document.documentId, {
2139
+ ...args22,
2140
+ data: sanitizedInputData
2141
+ });
2142
+ }
2143
+ return strapi2.documents(uid).create({
2144
+ ...args22,
2145
+ data: sanitizedInputData
2146
+ });
1998
2147
  }
1999
2148
  });
2000
2149
  };
2001
2150
  const addDeleteMutation = (t, contentType2) => {
2002
2151
  const { uid } = contentType2;
2003
2152
  const deleteMutationName = getDeleteMutationTypeName(contentType2);
2004
- const responseTypeName = getEntityResponseName(contentType2);
2153
+ const { DELETE_MUTATION_RESPONSE_TYPE_NAME: DELETE_MUTATION_RESPONSE_TYPE_NAME2 } = strapi2.plugin("graphql").service("constants");
2005
2154
  t.field(deleteMutationName, {
2006
- type: responseTypeName,
2155
+ type: DELETE_MUTATION_RESPONSE_TYPE_NAME2,
2156
+ extensions: {
2157
+ strapi: {
2158
+ contentType: contentType2
2159
+ }
2160
+ },
2007
2161
  args: {},
2008
- async resolve(parent, args2, ctx) {
2009
- const transformedArgs = transformArgs(args2, { contentType: contentType2 });
2010
- const { delete: deleteResolver } = getService("builders").get("content-api").buildMutationsResolvers({ contentType: contentType2 });
2011
- await validate.contentAPI.query(transformedArgs, contentType2, { auth: ctx?.state?.auth });
2012
- const sanitizedQuery = await sanitize.contentAPI.query(transformedArgs, contentType2, {
2013
- auth: ctx?.state?.auth
2014
- });
2015
- const entity2 = await strapi2.entityService.findMany(uid, sanitizedQuery);
2016
- if (!entity2) {
2017
- throw new NotFoundError("Entity not found");
2162
+ async resolve(parent, args22) {
2163
+ const document = await strapi2.db?.query(uid).findOne();
2164
+ if (!document) {
2165
+ throw new NotFoundError("Document not found");
2018
2166
  }
2019
- const value = await deleteResolver(parent, { id: entity2.id, params: transformedArgs });
2020
- return toEntityResponse(value, { args: transformedArgs, resourceUID: uid });
2167
+ await strapi2.documents(uid).delete(document.documentId, args22);
2168
+ return document;
2021
2169
  }
2022
2170
  });
2023
2171
  };
@@ -2104,9 +2252,9 @@ const contentType = ({ strapi: strapi2 }) => {
2104
2252
  const validAttributes = Object.entries(attributes2).filter(
2105
2253
  ([attributeName]) => extension.shadowCRUD(contentType2.uid).field(attributeName).hasFiltersEnabeld()
2106
2254
  );
2107
- const isIDFilterEnabled = extension.shadowCRUD(contentType2.uid).field("id").hasFiltersEnabeld();
2255
+ const isIDFilterEnabled = extension.shadowCRUD(contentType2.uid).field("documentId").hasFiltersEnabeld();
2108
2256
  if (contentType2.kind === "collectionType" && isIDFilterEnabled) {
2109
- t.field("id", { type: getScalarFilterInputTypeName("ID") });
2257
+ t.field("documentId", { type: getScalarFilterInputTypeName("ID") });
2110
2258
  }
2111
2259
  for (const [attributeName, attribute] of validAttributes) {
2112
2260
  if (isStrapiScalar(attribute)) {
@@ -2266,12 +2414,7 @@ const associationResolvers = ({ strapi: strapi2 }) => {
2266
2414
  const sanitizedQuery = await sanitize.contentAPI.query(transformedArgs, targetContentType, {
2267
2415
  auth
2268
2416
  });
2269
- const data = await strapi2.entityService.load(
2270
- contentTypeUID,
2271
- parent,
2272
- attributeName,
2273
- sanitizedQuery
2274
- );
2417
+ const data = await strapi2.db?.query(contentTypeUID).load(parent, attributeName, sanitizedQuery);
2275
2418
  const info = {
2276
2419
  args: sanitizedQuery,
2277
2420
  resourceUID: targetUID
@@ -2282,7 +2425,7 @@ const associationResolvers = ({ strapi: strapi2 }) => {
2282
2425
  return sanitize.contentAPI.output(dataToSanitize, contentType2, { auth });
2283
2426
  };
2284
2427
  const unwrapData = get(attributeName);
2285
- const sanitizeMorphAttribute = pipeAsync(wrapData, sanitizeData, unwrapData);
2428
+ const sanitizeMorphAttribute = async.pipe(wrapData, sanitizeData, unwrapData);
2286
2429
  return sanitizeMorphAttribute(data);
2287
2430
  }
2288
2431
  if (isToMany) {
@@ -2297,49 +2440,35 @@ const queriesResolvers = ({ strapi: strapi2 }) => ({
2297
2440
  buildQueriesResolvers({ contentType: contentType2 }) {
2298
2441
  const { uid } = contentType2;
2299
2442
  return {
2300
- async find(parent, args2, ctx) {
2443
+ async findMany(parent, args2, ctx) {
2301
2444
  await validate.contentAPI.query(args2, contentType2, {
2302
2445
  auth: ctx?.state?.auth
2303
2446
  });
2304
2447
  const sanitizedQuery = await sanitize.contentAPI.query(args2, contentType2, {
2305
2448
  auth: ctx?.state?.auth
2306
2449
  });
2307
- return strapi2.entityService.findMany(uid, sanitizedQuery);
2450
+ return strapi2.documents(uid).findMany({ status: "published", ...sanitizedQuery });
2308
2451
  },
2309
- async findOne(parent, args2, ctx) {
2452
+ async findFirst(parent, args2, ctx) {
2310
2453
  await validate.contentAPI.query(args2, contentType2, {
2311
2454
  auth: ctx?.state?.auth
2312
2455
  });
2313
2456
  const sanitizedQuery = await sanitize.contentAPI.query(args2, contentType2, {
2314
2457
  auth: ctx?.state?.auth
2315
2458
  });
2316
- return strapi2.entityService.findOne(uid, args2.id, omit("id", sanitizedQuery));
2317
- }
2318
- };
2319
- }
2320
- });
2321
- const pickCreateArgs = pick(["params", "data", "files"]);
2322
- const mutationsResolvers = ({ strapi: strapi2 }) => ({
2323
- buildMutationsResolvers({ contentType: contentType2 }) {
2324
- const { uid } = contentType2;
2325
- return {
2326
- async create(parent, args2) {
2327
- const params = pickCreateArgs(args2);
2328
- return strapi2.entityService.create(uid, params);
2329
- },
2330
- async update(parent, args2) {
2331
- const { id, data } = args2;
2332
- return strapi2.entityService.update(uid, id, { data });
2459
+ return strapi2.documents(uid).findFirst({ status: "published", ...sanitizedQuery });
2333
2460
  },
2334
- async delete(parent, args2, ctx) {
2335
- const { id, ...rest } = args2;
2336
- await validate.contentAPI.query(rest, contentType2, {
2461
+ async findOne(parent, args2, ctx) {
2462
+ await validate.contentAPI.query(args2, contentType2, {
2337
2463
  auth: ctx?.state?.auth
2338
2464
  });
2339
- const sanitizedQuery = await sanitize.contentAPI.query(rest, contentType2, {
2465
+ const sanitizedQuery = await sanitize.contentAPI.query(args2, contentType2, {
2340
2466
  auth: ctx?.state?.auth
2341
2467
  });
2342
- return strapi2.entityService.delete(uid, id, sanitizedQuery);
2468
+ return strapi2.documents(uid).findOne(args2.documentId, {
2469
+ status: "published",
2470
+ ...omit(["id", "documentId"], sanitizedQuery)
2471
+ });
2343
2472
  }
2344
2473
  };
2345
2474
  }
@@ -2361,7 +2490,7 @@ const componentResolvers = ({ strapi: strapi2 }) => ({
2361
2490
  const sanitizedQuery = await sanitize.contentAPI.query(transformedArgs, component, {
2362
2491
  auth: ctx?.state?.auth
2363
2492
  });
2364
- return strapi2.entityService.load(contentTypeUID, parent, attributeName, sanitizedQuery);
2493
+ return strapi2.db?.query(contentTypeUID).load(parent, attributeName, sanitizedQuery);
2365
2494
  };
2366
2495
  }
2367
2496
  });
@@ -2371,18 +2500,37 @@ const dynamicZoneResolvers = ({ strapi: strapi2 }) => ({
2371
2500
  attributeName
2372
2501
  }) {
2373
2502
  return async (parent) => {
2374
- return strapi2.entityService.load(contentTypeUID, parent, attributeName);
2503
+ return strapi2.db?.query(contentTypeUID).load(parent, attributeName);
2375
2504
  };
2376
2505
  }
2377
2506
  });
2507
+ const paginationResolvers = ({ strapi: strapi2 }) => ({
2508
+ async resolvePagination(parent, _, ctx) {
2509
+ const { args: args2, resourceUID } = parent.info;
2510
+ const { start, limit } = args2;
2511
+ const safeLimit = Math.max(limit, 1);
2512
+ const contentType2 = strapi2.getModel(resourceUID);
2513
+ await validate.contentAPI.query(args2, contentType2, {
2514
+ auth: ctx?.state?.auth
2515
+ });
2516
+ const sanitizedQuery = await sanitize.contentAPI.query(args2, contentType2, {
2517
+ auth: ctx?.state?.auth
2518
+ });
2519
+ const total = await strapi2.documents(resourceUID).count(sanitizedQuery);
2520
+ const pageSize = limit === -1 ? total - start : safeLimit;
2521
+ const pageCount = limit === -1 ? safeLimit : Math.ceil(total / safeLimit);
2522
+ const page = limit === -1 ? safeLimit : Math.floor(start / safeLimit) + 1;
2523
+ return { total, page, pageSize, pageCount };
2524
+ }
2525
+ });
2378
2526
  const resolvers = (context) => ({
2379
2527
  // Generics
2380
2528
  ...associationResolvers(context),
2381
2529
  // Builders
2382
- ...mutationsResolvers(context),
2383
2530
  ...queriesResolvers(context),
2384
2531
  ...componentResolvers(context),
2385
- ...dynamicZoneResolvers(context)
2532
+ ...dynamicZoneResolvers(context),
2533
+ ...paginationResolvers(context)
2386
2534
  });
2387
2535
  const AND_FIELD_NAME = "and";
2388
2536
  const andOperator = () => ({
@@ -2598,18 +2746,10 @@ const operators = {
2598
2746
  };
2599
2747
  const operators$1 = ({ strapi: strapi2 }) => mapValues((opCtor) => opCtor({ strapi: strapi2 }), operators);
2600
2748
  const { withDefaultPagination } = pagination$1;
2601
- const { hasDraftAndPublish } = contentTypes;
2602
2749
  const utils = ({ strapi: strapi2 }) => {
2603
2750
  const { service: getService } = strapi2.plugin("graphql");
2604
2751
  return {
2605
- /**
2606
- * Get every args for a given content type
2607
- * @param {object} contentType
2608
- * @param {object} options
2609
- * @param {boolean} options.multiple
2610
- * @return {object}
2611
- */
2612
- getContentTypeArgs(contentType2, { multiple = true } = {}) {
2752
+ getContentTypeArgs(contentType2, { multiple = true, isNested = false } = {}) {
2613
2753
  const { naming: naming2 } = getService("utils");
2614
2754
  const { args: args2 } = getService("internals");
2615
2755
  const { modelType } = contentType2;
@@ -2625,22 +2765,25 @@ const utils = ({ strapi: strapi2 }) => {
2625
2765
  const { kind } = contentType2;
2626
2766
  if (kind === "collectionType") {
2627
2767
  if (!multiple) {
2628
- return { id: "ID" };
2768
+ return {
2769
+ documentId: nonNull(idArg()),
2770
+ status: args2.PublicationStatusArg
2771
+ };
2629
2772
  }
2630
2773
  const params = {
2631
2774
  filters: naming2.getFiltersInputTypeName(contentType2),
2632
2775
  pagination: args2.PaginationArg,
2633
2776
  sort: args2.SortArg
2634
2777
  };
2635
- if (hasDraftAndPublish(contentType2)) {
2636
- Object.assign(params, { publicationState: args2.PublicationStateArg });
2778
+ if (!isNested) {
2779
+ Object.assign(params, { status: args2.PublicationStatusArg });
2637
2780
  }
2638
2781
  return params;
2639
2782
  }
2640
2783
  if (kind === "singleType") {
2641
2784
  const params = {};
2642
- if (hasDraftAndPublish(contentType2)) {
2643
- Object.assign(params, { publicationState: args2.PublicationStateArg });
2785
+ if (!isNested) {
2786
+ Object.assign(params, { status: args2.PublicationStatusArg });
2644
2787
  }
2645
2788
  return params;
2646
2789
  }
@@ -2705,7 +2848,6 @@ const buildersFactories = [
2705
2848
  enums,
2706
2849
  dynamicZone,
2707
2850
  entity,
2708
- entityMeta,
2709
2851
  typeBuilder,
2710
2852
  response,
2711
2853
  responseCollection,