@strapi/utils 5.0.0-beta.1 → 5.0.0-beta.11

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 (37) hide show
  1. package/dist/async.d.ts +5 -11
  2. package/dist/async.d.ts.map +1 -1
  3. package/dist/content-types.d.ts +16 -6
  4. package/dist/content-types.d.ts.map +1 -1
  5. package/dist/convert-query-params.d.ts.map +1 -1
  6. package/dist/file.d.ts +0 -1
  7. package/dist/file.d.ts.map +1 -1
  8. package/dist/hooks.d.ts.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +325 -154
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +312 -141
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/pagination.d.ts +34 -4
  16. package/dist/pagination.d.ts.map +1 -1
  17. package/dist/parse-type.d.ts.map +1 -1
  18. package/dist/sanitize/sanitizers.d.ts +1 -1
  19. package/dist/sanitize/sanitizers.d.ts.map +1 -1
  20. package/dist/set-creator-fields.d.ts.map +1 -1
  21. package/dist/traverse/factory.d.ts +2 -4
  22. package/dist/traverse/factory.d.ts.map +1 -1
  23. package/dist/traverse/query-populate.d.ts.map +1 -1
  24. package/dist/traverse-entity.d.ts +10 -2
  25. package/dist/traverse-entity.d.ts.map +1 -1
  26. package/dist/validate/index.d.ts.map +1 -1
  27. package/dist/validate/utils.d.ts +2 -2
  28. package/dist/validate/utils.d.ts.map +1 -1
  29. package/dist/validate/visitors/index.d.ts +1 -0
  30. package/dist/validate/visitors/index.d.ts.map +1 -1
  31. package/dist/validate/visitors/throw-unrecognized-fields.d.ts +4 -0
  32. package/dist/validate/visitors/throw-unrecognized-fields.d.ts.map +1 -0
  33. package/dist/validators.d.ts +2 -2
  34. package/dist/validators.d.ts.map +1 -1
  35. package/dist/zod.d.ts +3 -0
  36. package/dist/zod.d.ts.map +1 -0
  37. package/package.json +11 -9
package/dist/index.mjs CHANGED
@@ -1,5 +1,7 @@
1
- import _$1, { kebabCase } from "lodash";
2
- import { has, union, getOr, assoc, assign, cloneDeep, remove, eq, curry, isObject, isNil, clone, isArray, isEmpty, toPath, defaults, isString, mergeAll, get, toNumber, isInteger, pick, omit, trim, pipe as pipe$1, split, map as map$1, flatten, first, identity, constant, join, merge, trimChars, trimCharsEnd, trimCharsStart, isNumber } from "lodash/fp";
1
+ import * as _ from "lodash";
2
+ import ___default, { kebabCase } from "lodash";
3
+ import * as dates$1 from "date-fns";
4
+ import { has, union, getOr, assoc, assign, cloneDeep, remove, eq, curry, isObject, isNil, clone, isArray, isEmpty, toPath, defaults, isString, get, toNumber, isInteger, pick, omit, trim, pipe as pipe$1, split, map as map$1, flatten, first, identity, constant, join, merge, trimChars, trimCharsEnd, trimCharsStart, isNumber } from "lodash/fp";
3
5
  import { randomUUID } from "crypto";
4
6
  import { machineIdSync } from "node-machine-id";
5
7
  import * as yup$1 from "yup";
@@ -9,6 +11,7 @@ import execa from "execa";
9
11
  import preferredPM from "preferred-pm";
10
12
  import { Writable } from "node:stream";
11
13
  import slugify from "@sindresorhus/slugify";
14
+ import { z } from "zod";
12
15
  function _mergeNamespaces(n, m) {
13
16
  for (var i = 0; i < m.length; i++) {
14
17
  const e = m[i];
@@ -28,8 +31,6 @@ function _mergeNamespaces(n, m) {
28
31
  }
29
32
  return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }));
30
33
  }
31
- const _ = require("lodash");
32
- const dates$1 = require("date-fns");
33
34
  const timeRegex = /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$/;
34
35
  const isDate = (v) => {
35
36
  return dates$1.isDate(v);
@@ -128,32 +129,32 @@ const parseType = (options) => {
128
129
  }
129
130
  };
130
131
  function envFn(key, defaultValue) {
131
- return _$1.has(process.env, key) ? process.env[key] : defaultValue;
132
+ return ___default.has(process.env, key) ? process.env[key] : defaultValue;
132
133
  }
133
134
  function getKey(key) {
134
135
  return process.env[key] ?? "";
135
136
  }
136
137
  const utils = {
137
138
  int(key, defaultValue) {
138
- if (!_$1.has(process.env, key)) {
139
+ if (!___default.has(process.env, key)) {
139
140
  return defaultValue;
140
141
  }
141
142
  return parseInt(getKey(key), 10);
142
143
  },
143
144
  float(key, defaultValue) {
144
- if (!_$1.has(process.env, key)) {
145
+ if (!___default.has(process.env, key)) {
145
146
  return defaultValue;
146
147
  }
147
148
  return parseFloat(getKey(key));
148
149
  },
149
150
  bool(key, defaultValue) {
150
- if (!_$1.has(process.env, key)) {
151
+ if (!___default.has(process.env, key)) {
151
152
  return defaultValue;
152
153
  }
153
154
  return getKey(key) === "true";
154
155
  },
155
156
  json(key, defaultValue) {
156
- if (!_$1.has(process.env, key)) {
157
+ if (!___default.has(process.env, key)) {
157
158
  return defaultValue;
158
159
  }
159
160
  try {
@@ -166,7 +167,7 @@ const utils = {
166
167
  }
167
168
  },
168
169
  array(key, defaultValue) {
169
- if (!_$1.has(process.env, key)) {
170
+ if (!___default.has(process.env, key)) {
170
171
  return defaultValue;
171
172
  }
172
173
  let value = getKey(key);
@@ -174,11 +175,11 @@ const utils = {
174
175
  value = value.substring(1, value.length - 1);
175
176
  }
176
177
  return value.split(",").map((v) => {
177
- return _$1.trim(_$1.trim(v, " "), '"');
178
+ return ___default.trim(___default.trim(v, " "), '"');
178
179
  });
179
180
  },
180
181
  date(key, defaultValue) {
181
- if (!_$1.has(process.env, key)) {
182
+ if (!___default.has(process.env, key)) {
182
183
  return defaultValue;
183
184
  }
184
185
  return new Date(getKey(key));
@@ -245,12 +246,12 @@ const getCreatorFields = (model) => {
245
246
  const getNonWritableAttributes = (model) => {
246
247
  if (!model)
247
248
  return [];
248
- const nonWritableAttributes = _$1.reduce(
249
+ const nonWritableAttributes = ___default.reduce(
249
250
  model.attributes,
250
251
  (acc, attr, attrName) => attr.writable === false ? acc.concat(attrName) : acc,
251
252
  []
252
253
  );
253
- return _$1.uniq([
254
+ return ___default.uniq([
254
255
  ID_ATTRIBUTE$4,
255
256
  DOC_ID_ATTRIBUTE$4,
256
257
  ...getTimestamps(model),
@@ -260,28 +261,37 @@ const getNonWritableAttributes = (model) => {
260
261
  const getWritableAttributes = (model) => {
261
262
  if (!model)
262
263
  return [];
263
- return _$1.difference(Object.keys(model.attributes), getNonWritableAttributes(model));
264
+ return ___default.difference(Object.keys(model.attributes), getNonWritableAttributes(model));
264
265
  };
265
266
  const isWritableAttribute = (model, attributeName) => {
266
267
  return getWritableAttributes(model).includes(attributeName);
267
268
  };
268
269
  const getNonVisibleAttributes = (model) => {
269
- const nonVisibleAttributes = _$1.reduce(
270
+ const nonVisibleAttributes = ___default.reduce(
270
271
  model.attributes,
271
272
  (acc, attr, attrName) => attr.visible === false ? acc.concat(attrName) : acc,
272
273
  []
273
274
  );
274
- return _$1.uniq([ID_ATTRIBUTE$4, DOC_ID_ATTRIBUTE$4, ...getTimestamps(model), ...nonVisibleAttributes]);
275
+ return ___default.uniq([ID_ATTRIBUTE$4, DOC_ID_ATTRIBUTE$4, ...getTimestamps(model), ...nonVisibleAttributes]);
275
276
  };
276
277
  const getVisibleAttributes = (model) => {
277
- return _$1.difference(_$1.keys(model.attributes), getNonVisibleAttributes(model));
278
+ return ___default.difference(___default.keys(model.attributes), getNonVisibleAttributes(model));
278
279
  };
279
280
  const isVisibleAttribute = (model, attributeName) => {
280
281
  return getVisibleAttributes(model).includes(attributeName);
281
282
  };
282
- const getOptions = (model) => _$1.assign({ draftAndPublish: false }, _$1.get(model, "options", {}));
283
- const hasDraftAndPublish = (model) => _$1.get(model, "options.draftAndPublish", false) === true;
284
- const isDraft = (data, model) => hasDraftAndPublish(model) && _$1.get(data, PUBLISHED_AT_ATTRIBUTE$1) === null;
283
+ const getOptions = (model) => ___default.assign({ draftAndPublish: false }, ___default.get(model, "options", {}));
284
+ const hasDraftAndPublish = (model) => ___default.get(model, "options.draftAndPublish", false) === true;
285
+ const isDraft = (data, model) => hasDraftAndPublish(model) && ___default.get(data, PUBLISHED_AT_ATTRIBUTE$1) === null;
286
+ const isSchema = (data) => {
287
+ return typeof data === "object" && data !== null && "modelType" in data && typeof data.modelType === "string" && ["component", "contentType"].includes(data.modelType);
288
+ };
289
+ const isComponentSchema = (data) => {
290
+ return isSchema(data) && data.modelType === "component";
291
+ };
292
+ const isContentTypeSchema = (data) => {
293
+ return isSchema(data) && data.modelType === "contentType";
294
+ };
285
295
  const isSingleType = ({ kind = COLLECTION_TYPE }) => kind === SINGLE_TYPE;
286
296
  const isCollectionType = ({ kind = COLLECTION_TYPE }) => kind === COLLECTION_TYPE;
287
297
  const isKind = (kind) => (model) => model.kind === kind;
@@ -290,9 +300,9 @@ const getStoredPrivateAttributes = (model) => union(
290
300
  getOr([], "options.privateAttributes", model)
291
301
  );
292
302
  const getPrivateAttributes = (model) => {
293
- return _$1.union(
303
+ return ___default.union(
294
304
  getStoredPrivateAttributes(model),
295
- _$1.keys(_$1.pickBy(model.attributes, (attr) => !!attr.private))
305
+ ___default.keys(___default.pickBy(model.attributes, (attr) => !!attr.private))
296
306
  );
297
307
  };
298
308
  const isPrivateAttribute = (model, attributeName) => {
@@ -302,17 +312,22 @@ const isPrivateAttribute = (model, attributeName) => {
302
312
  return getStoredPrivateAttributes(model).includes(attributeName);
303
313
  };
304
314
  const isScalarAttribute = (attribute) => {
305
- return !["media", "component", "relation", "dynamiczone"].includes(attribute?.type);
315
+ return attribute && !["media", "component", "relation", "dynamiczone"].includes(attribute.type);
316
+ };
317
+ const getDoesAttributeRequireValidation = (attribute) => {
318
+ return attribute.required || attribute.unique || Object.prototype.hasOwnProperty.call(attribute, "max") || Object.prototype.hasOwnProperty.call(attribute, "min") || Object.prototype.hasOwnProperty.call(attribute, "maxLength") || Object.prototype.hasOwnProperty.call(attribute, "minLength");
306
319
  };
307
320
  const isMediaAttribute = (attribute) => attribute?.type === "media";
308
321
  const isRelationalAttribute = (attribute) => attribute?.type === "relation";
322
+ const HAS_RELATION_REORDERING = ["manyToMany", "manyToOne", "oneToMany"];
323
+ const hasRelationReordering = (attribute) => isRelationalAttribute(attribute) && HAS_RELATION_REORDERING.includes(attribute.relation);
309
324
  const isComponentAttribute = (attribute) => ["component", "dynamiczone"].includes(attribute?.type);
310
- const isDynamicZoneAttribute = (attribute) => attribute?.type === "dynamiczone";
325
+ const isDynamicZoneAttribute = (attribute) => !!attribute && attribute.type === "dynamiczone";
311
326
  const isMorphToRelationalAttribute = (attribute) => {
312
- return isRelationalAttribute(attribute) && attribute?.relation?.startsWith?.("morphTo");
327
+ return !!attribute && isRelationalAttribute(attribute) && attribute.relation?.startsWith?.("morphTo");
313
328
  };
314
329
  const getComponentAttributes = (schema) => {
315
- return _$1.reduce(
330
+ return ___default.reduce(
316
331
  schema.attributes,
317
332
  (acc, attr, attrName) => {
318
333
  if (isComponentAttribute(attr))
@@ -323,7 +338,7 @@ const getComponentAttributes = (schema) => {
323
338
  );
324
339
  };
325
340
  const getScalarAttributes = (schema) => {
326
- return _$1.reduce(
341
+ return ___default.reduce(
327
342
  schema.attributes,
328
343
  (acc, attr, attrName) => {
329
344
  if (isScalarAttribute(attr))
@@ -333,11 +348,22 @@ const getScalarAttributes = (schema) => {
333
348
  []
334
349
  );
335
350
  };
351
+ const getRelationalAttributes = (schema) => {
352
+ return ___default.reduce(
353
+ schema.attributes,
354
+ (acc, attr, attrName) => {
355
+ if (isRelationalAttribute(attr))
356
+ acc.push(attrName);
357
+ return acc;
358
+ },
359
+ []
360
+ );
361
+ };
336
362
  const isTypedAttribute = (attribute, type) => {
337
- return _$1.has(attribute, "type") && attribute.type === type;
363
+ return ___default.has(attribute, "type") && attribute.type === type;
338
364
  };
339
365
  const getContentTypeRoutePrefix = (contentType) => {
340
- return isSingleType(contentType) ? _$1.kebabCase(contentType.info.singularName) : _$1.kebabCase(contentType.info.pluralName);
366
+ return isSingleType(contentType) ? ___default.kebabCase(contentType.info.singularName) : ___default.kebabCase(contentType.info.pluralName);
341
367
  };
342
368
  const contentTypes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
343
369
  __proto__: null,
@@ -345,17 +371,22 @@ const contentTypes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
345
371
  getComponentAttributes,
346
372
  getContentTypeRoutePrefix,
347
373
  getCreatorFields,
374
+ getDoesAttributeRequireValidation,
348
375
  getNonVisibleAttributes,
349
376
  getNonWritableAttributes,
350
377
  getOptions,
351
378
  getPrivateAttributes,
379
+ getRelationalAttributes,
352
380
  getScalarAttributes,
353
381
  getTimestamps,
354
382
  getVisibleAttributes,
355
383
  getWritableAttributes,
356
384
  hasDraftAndPublish,
385
+ hasRelationReordering,
357
386
  isCollectionType,
358
387
  isComponentAttribute,
388
+ isComponentSchema,
389
+ isContentTypeSchema,
359
390
  isDraft,
360
391
  isDynamicZoneAttribute,
361
392
  isKind,
@@ -364,6 +395,7 @@ const contentTypes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
364
395
  isPrivateAttribute,
365
396
  isRelationalAttribute,
366
397
  isScalarAttribute,
398
+ isSchema,
367
399
  isSingleType,
368
400
  isTypedAttribute,
369
401
  isVisibleAttribute,
@@ -518,28 +550,29 @@ const providerFactory = (options = {}) => {
518
550
  };
519
551
  const traverseEntity = async (visitor2, options, entity) => {
520
552
  const { path = { raw: null, attribute: null }, schema, getModel } = options;
553
+ let parent = options.parent;
521
554
  const traverseMorphRelationTarget = async (visitor22, path2, entry) => {
522
555
  const targetSchema = getModel(entry.__type);
523
- const traverseOptions = { schema: targetSchema, path: path2, getModel };
556
+ const traverseOptions = { schema: targetSchema, path: path2, getModel, parent };
524
557
  return traverseEntity(visitor22, traverseOptions, entry);
525
558
  };
526
559
  const traverseRelationTarget = (schema2) => async (visitor22, path2, entry) => {
527
- const traverseOptions = { schema: schema2, path: path2, getModel };
560
+ const traverseOptions = { schema: schema2, path: path2, getModel, parent };
528
561
  return traverseEntity(visitor22, traverseOptions, entry);
529
562
  };
530
563
  const traverseMediaTarget = async (visitor22, path2, entry) => {
531
564
  const targetSchemaUID = "plugin::upload.file";
532
565
  const targetSchema = getModel(targetSchemaUID);
533
- const traverseOptions = { schema: targetSchema, path: path2, getModel };
566
+ const traverseOptions = { schema: targetSchema, path: path2, getModel, parent };
534
567
  return traverseEntity(visitor22, traverseOptions, entry);
535
568
  };
536
569
  const traverseComponent = async (visitor22, path2, schema2, entry) => {
537
- const traverseOptions = { schema: schema2, path: path2, getModel };
570
+ const traverseOptions = { schema: schema2, path: path2, getModel, parent };
538
571
  return traverseEntity(visitor22, traverseOptions, entry);
539
572
  };
540
573
  const visitDynamicZoneEntry = async (visitor22, path2, entry) => {
541
574
  const targetSchema = getModel(entry.__component);
542
- const traverseOptions = { schema: targetSchema, path: path2, getModel };
575
+ const traverseOptions = { schema: targetSchema, path: path2, getModel, parent };
543
576
  return traverseEntity(visitor22, traverseOptions, entry);
544
577
  };
545
578
  if (!isObject(entity) || isNil(schema)) {
@@ -551,9 +584,6 @@ const traverseEntity = async (visitor2, options, entity) => {
551
584
  for (let i = 0; i < keys.length; i += 1) {
552
585
  const key = keys[i];
553
586
  const attribute = schema.attributes[key];
554
- if (isNil(attribute)) {
555
- continue;
556
- }
557
587
  const newPath = { ...path };
558
588
  newPath.raw = isNil(path.raw) ? key : `${path.raw}.${key}`;
559
589
  if (!isNil(attribute)) {
@@ -566,13 +596,15 @@ const traverseEntity = async (visitor2, options, entity) => {
566
596
  value: copy[key],
567
597
  attribute,
568
598
  path: newPath,
569
- getModel
599
+ getModel,
600
+ parent
570
601
  };
571
602
  await visitor2(visitorOptions, visitorUtils);
572
603
  const value = copy[key];
573
- if (isNil(value)) {
604
+ if (isNil(value) || isNil(attribute)) {
574
605
  continue;
575
606
  }
607
+ parent = { schema, key, attribute, path: newPath };
576
608
  if (isRelationalAttribute(attribute)) {
577
609
  const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
578
610
  const method = isMorphRelation ? traverseMorphRelationTarget : traverseRelationTarget(getModel(attribute.target));
@@ -870,7 +902,7 @@ const convertCountQueryParams = (countQuery) => {
870
902
  const convertOrderingQueryParams = (ordering) => {
871
903
  return ordering;
872
904
  };
873
- const isPlainObject = (value) => _$1.isPlainObject(value);
905
+ const isPlainObject = (value) => ___default.isPlainObject(value);
874
906
  const isStringArray$3 = (value) => isArray(value) && value.every(isString);
875
907
  const createTransformer = ({ getModel }) => {
876
908
  const convertSortQueryParams = (sortQuery) => {
@@ -903,7 +935,7 @@ const createTransformer = ({ getModel }) => {
903
935
  throw new Error("Field cannot be empty");
904
936
  }
905
937
  validateOrder(order);
906
- return _$1.set({}, field, order);
938
+ return ___default.set({}, field, order);
907
939
  };
908
940
  const convertNestedSortQueryParam = (sortQuery) => {
909
941
  const transformedSort = {};
@@ -921,15 +953,15 @@ const createTransformer = ({ getModel }) => {
921
953
  return transformedSort;
922
954
  };
923
955
  const convertStartQueryParams = (startQuery) => {
924
- const startAsANumber = _$1.toNumber(startQuery);
925
- if (!_$1.isInteger(startAsANumber) || startAsANumber < 0) {
956
+ const startAsANumber = ___default.toNumber(startQuery);
957
+ if (!___default.isInteger(startAsANumber) || startAsANumber < 0) {
926
958
  throw new Error(`convertStartQueryParams expected a positive integer got ${startAsANumber}`);
927
959
  }
928
960
  return startAsANumber;
929
961
  };
930
962
  const convertLimitQueryParams = (limitQuery) => {
931
- const limitAsANumber = _$1.toNumber(limitQuery);
932
- if (!_$1.isInteger(limitAsANumber) || limitAsANumber !== -1 && limitAsANumber < 0) {
963
+ const limitAsANumber = ___default.toNumber(limitQuery);
964
+ if (!___default.isInteger(limitAsANumber) || limitAsANumber !== -1 && limitAsANumber < 0) {
933
965
  throw new Error(`convertLimitQueryParams expected a positive integer got ${limitAsANumber}`);
934
966
  }
935
967
  if (limitAsANumber === -1) {
@@ -975,44 +1007,62 @@ const createTransformer = ({ getModel }) => {
975
1007
  return true;
976
1008
  }
977
1009
  if (typeof populate2 === "string") {
978
- return populate2.split(",").map((value) => _$1.trim(value));
1010
+ return populate2.split(",").map((value) => ___default.trim(value));
979
1011
  }
980
1012
  if (Array.isArray(populate2)) {
981
- return _$1.uniq(
1013
+ return ___default.uniq(
982
1014
  populate2.flatMap((value) => {
983
1015
  if (typeof value !== "string") {
984
1016
  throw new InvalidPopulateError();
985
1017
  }
986
- return value.split(",").map((value2) => _$1.trim(value2));
1018
+ return value.split(",").map((value2) => ___default.trim(value2));
987
1019
  })
988
1020
  );
989
1021
  }
990
- if (_$1.isPlainObject(populate2)) {
1022
+ if (___default.isPlainObject(populate2)) {
991
1023
  return convertPopulateObject(populate2, schema);
992
1024
  }
993
1025
  throw new InvalidPopulateError();
994
1026
  };
995
- const hasFragmentPopulateDefined = (populate2) => {
1027
+ const hasPopulateFragmentDefined = (populate2) => {
996
1028
  return typeof populate2 === "object" && "on" in populate2 && !isNil(populate2.on);
997
1029
  };
1030
+ const hasCountDefined = (populate2) => {
1031
+ return typeof populate2 === "object" && "count" in populate2 && typeof populate2.count === "boolean";
1032
+ };
998
1033
  const convertPopulateObject = (populate2, schema) => {
999
1034
  if (!schema) {
1000
1035
  return {};
1001
1036
  }
1002
1037
  const { attributes } = schema;
1003
1038
  return Object.entries(populate2).reduce((acc, [key, subPopulate]) => {
1004
- if (_$1.isBoolean(subPopulate)) {
1005
- return { ...acc, [key]: subPopulate };
1039
+ if (___default.isString(subPopulate)) {
1040
+ try {
1041
+ const subPopulateAsBoolean = parseType({ type: "boolean", value: subPopulate });
1042
+ return subPopulateAsBoolean === true ? { ...acc, [key]: true } : acc;
1043
+ } catch {
1044
+ }
1045
+ }
1046
+ if (___default.isBoolean(subPopulate)) {
1047
+ return subPopulate === true ? { ...acc, [key]: true } : acc;
1006
1048
  }
1007
1049
  const attribute = attributes[key];
1008
1050
  if (!attribute) {
1009
1051
  return acc;
1010
1052
  }
1011
- const isAllowedAttributeForFragmentPopulate = isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);
1012
- if (isAllowedAttributeForFragmentPopulate && hasFragmentPopulateDefined(subPopulate)) {
1013
- return {
1014
- ...acc,
1015
- [key]: {
1053
+ const isMorphLikeRelationalAttribute = isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);
1054
+ if (isMorphLikeRelationalAttribute) {
1055
+ const hasInvalidProperties = Object.keys(subPopulate).some(
1056
+ (key2) => !["on", "count"].includes(key2)
1057
+ );
1058
+ if (hasInvalidProperties) {
1059
+ throw new Error(
1060
+ `Invalid nested populate for ${schema.info?.singularName}.${key} (${schema.uid}). Expected a fragment ("on") or "count" but found ${JSON.stringify(subPopulate)}`
1061
+ );
1062
+ }
1063
+ const newSubPopulate = {};
1064
+ if (hasPopulateFragmentDefined(subPopulate)) {
1065
+ Object.assign(newSubPopulate, {
1016
1066
  on: Object.entries(subPopulate.on).reduce(
1017
1067
  (acc2, [type, typeSubPopulate]) => ({
1018
1068
  ...acc2,
@@ -1020,21 +1070,15 @@ const createTransformer = ({ getModel }) => {
1020
1070
  }),
1021
1071
  {}
1022
1072
  )
1023
- }
1024
- };
1025
- }
1026
- if (isDynamicZoneAttribute(attribute)) {
1027
- const populates = attribute.components.map((uid) => getModel(uid)).map((schema2) => convertNestedPopulate(subPopulate, schema2)).map((populate22) => populate22 === true ? {} : populate22).filter((populate22) => populate22 !== false);
1028
- if (isEmpty(populates)) {
1029
- return acc;
1073
+ });
1030
1074
  }
1031
- return {
1032
- ...acc,
1033
- [key]: mergeAll(populates)
1034
- };
1075
+ if (hasCountDefined(subPopulate)) {
1076
+ Object.assign(newSubPopulate, { count: subPopulate.count });
1077
+ }
1078
+ return { ...acc, [key]: newSubPopulate };
1035
1079
  }
1036
- if (isMorphToRelationalAttribute(attribute)) {
1037
- return { ...acc, [key]: convertNestedPopulate(subPopulate, void 0) };
1080
+ if (!isMorphLikeRelationalAttribute && hasPopulateFragmentDefined(subPopulate)) {
1081
+ throw new Error(`Using fragments is not permitted to populate "${key}" in "${schema.uid}"`);
1038
1082
  }
1039
1083
  let targetSchemaUID;
1040
1084
  if (attribute.type === "relation") {
@@ -1061,10 +1105,10 @@ const createTransformer = ({ getModel }) => {
1061
1105
  }, {});
1062
1106
  };
1063
1107
  const convertNestedPopulate = (subPopulate, schema) => {
1064
- if (_$1.isString(subPopulate)) {
1108
+ if (___default.isString(subPopulate)) {
1065
1109
  return parseType({ type: "boolean", value: subPopulate, forceCast: true });
1066
1110
  }
1067
- if (_$1.isBoolean(subPopulate)) {
1111
+ if (___default.isBoolean(subPopulate)) {
1068
1112
  return subPopulate;
1069
1113
  }
1070
1114
  if (!isPlainObject(subPopulate)) {
@@ -1110,12 +1154,12 @@ const createTransformer = ({ getModel }) => {
1110
1154
  return void 0;
1111
1155
  }
1112
1156
  if (typeof fields2 === "string") {
1113
- const fieldsValues = fields2.split(",").map((value) => _$1.trim(value));
1114
- return _$1.uniq([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3, ...fieldsValues]);
1157
+ const fieldsValues = fields2.split(",").map((value) => ___default.trim(value));
1158
+ return ___default.uniq([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3, ...fieldsValues]);
1115
1159
  }
1116
1160
  if (isStringArray$3(fields2)) {
1117
1161
  const fieldsValues = fields2.flatMap((value) => convertFieldsQueryParams(value, depth + 1)).filter((v) => !isNil(v));
1118
- return _$1.uniq([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3, ...fieldsValues]);
1162
+ return ___default.uniq([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3, ...fieldsValues]);
1119
1163
  }
1120
1164
  throw new Error("Invalid fields parameter. Expected a string or an array of strings");
1121
1165
  };
@@ -1790,7 +1834,8 @@ const populate = traverseFactory().intercept(isStringArray$1, async (visitor2, o
1790
1834
  return;
1791
1835
  }
1792
1836
  const newValue2 = await recurse(visitor2, { schema, path, getModel }, { on: value?.on });
1793
- set(key, { on: newValue2 });
1837
+ set(key, newValue2);
1838
+ return;
1794
1839
  }
1795
1840
  const targetSchemaUID = attribute.target;
1796
1841
  const targetSchema = getModel(targetSchemaUID);
@@ -1812,36 +1857,15 @@ const populate = traverseFactory().intercept(isStringArray$1, async (visitor2, o
1812
1857
  const targetSchema = getModel(attribute.component);
1813
1858
  const newValue = await recurse(visitor2, { schema: targetSchema, path, getModel }, value);
1814
1859
  set(key, newValue);
1815
- }).onDynamicZone(
1816
- async ({ key, value, attribute, schema, visitor: visitor2, path, getModel }, { set, recurse }) => {
1817
- if (isNil(value)) {
1818
- return;
1819
- }
1820
- if (isObject(value)) {
1821
- const { components } = attribute;
1822
- const newValue = {};
1823
- let newProperties = omit("on", value);
1824
- for (const componentUID of components) {
1825
- const componentSchema = getModel(componentUID);
1826
- const properties = await recurse(
1827
- visitor2,
1828
- { schema: componentSchema, path, getModel },
1829
- value
1830
- );
1831
- newProperties = merge(newProperties, properties);
1832
- }
1833
- Object.assign(newValue, newProperties);
1834
- if ("on" in value && value.on) {
1835
- const newOn = await recurse(visitor2, { schema, path, getModel }, { on: value.on });
1836
- Object.assign(newValue, newOn);
1837
- }
1838
- set(key, newValue);
1839
- } else {
1840
- const newValue = await recurse(visitor2, { schema, path, getModel }, value);
1841
- set(key, newValue);
1842
- }
1860
+ }).onDynamicZone(async ({ key, value, schema, visitor: visitor2, path, getModel }, { set, recurse }) => {
1861
+ if (isNil(value) || !isObject(value)) {
1862
+ return;
1843
1863
  }
1844
- );
1864
+ if ("on" in value && value.on) {
1865
+ const newOn = await recurse(visitor2, { schema, path, getModel }, { on: value.on });
1866
+ set(key, newOn);
1867
+ }
1868
+ });
1845
1869
  const traverseQueryPopulate = curry(populate.traverse);
1846
1870
  const isStringArray = (value) => isArray(value) && value.every(isString);
1847
1871
  const fields = traverseFactory().intercept(isStringArray, async (visitor2, options, fields2, { recurse }) => {
@@ -2140,13 +2164,16 @@ const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
2140
2164
  sanitizers,
2141
2165
  visitors: index$4
2142
2166
  }, Symbol.toStringTag, { value: "Module" }));
2143
- const throwInvalidParam = ({ key, path }) => {
2144
- const msg = path && path !== key ? `Invalid parameter ${key} at ${path}` : `Invalid parameter ${key}`;
2145
- throw new ValidationError(msg);
2167
+ const throwInvalidKey = ({ key, path }) => {
2168
+ const msg = path && path !== key ? `Invalid key ${key} at ${path}` : `Invalid key ${key}`;
2169
+ throw new ValidationError(msg, {
2170
+ key,
2171
+ path
2172
+ });
2146
2173
  };
2147
2174
  const visitor$3 = ({ key, attribute, path }) => {
2148
2175
  if (attribute?.type === "password") {
2149
- throwInvalidParam({ key, path: path.attribute });
2176
+ throwInvalidKey({ key, path: path.attribute });
2150
2177
  }
2151
2178
  };
2152
2179
  const visitor$2 = ({ schema, key, attribute, path }) => {
@@ -2155,7 +2182,7 @@ const visitor$2 = ({ schema, key, attribute, path }) => {
2155
2182
  }
2156
2183
  const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);
2157
2184
  if (isPrivate) {
2158
- throwInvalidParam({ key, path: path.attribute });
2185
+ throwInvalidKey({ key, path: path.attribute });
2159
2186
  }
2160
2187
  };
2161
2188
  const ACTIONS_TO_VERIFY = ["find"];
@@ -2173,7 +2200,7 @@ const throwRestrictedRelations = (auth) => async ({ data, key, attribute, schema
2173
2200
  const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);
2174
2201
  const isAllowed = await hasAccessToSomeScopes(scopes, auth);
2175
2202
  if (!isAllowed) {
2176
- throwInvalidParam({ key, path: path.attribute });
2203
+ throwInvalidKey({ key, path: path.attribute });
2177
2204
  }
2178
2205
  }
2179
2206
  };
@@ -2181,7 +2208,7 @@ const throwRestrictedRelations = (auth) => async ({ data, key, attribute, schema
2181
2208
  const scopes = ACTIONS_TO_VERIFY.map((action) => `${attribute.target}.${action}`);
2182
2209
  const isAllowed = await hasAccessToSomeScopes(scopes, auth);
2183
2210
  if (!isAllowed) {
2184
- throwInvalidParam({ key, path: path.attribute });
2211
+ throwInvalidKey({ key, path: path.attribute });
2185
2212
  }
2186
2213
  };
2187
2214
  const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);
@@ -2207,12 +2234,12 @@ const hasAccessToSomeScopes = async (scopes, auth) => {
2207
2234
  };
2208
2235
  const visitor$1 = ({ key, attribute, path }) => {
2209
2236
  if (isMorphToRelationalAttribute(attribute)) {
2210
- throwInvalidParam({ key, path: path.attribute });
2237
+ throwInvalidKey({ key, path: path.attribute });
2211
2238
  }
2212
2239
  };
2213
2240
  const visitor = ({ key, attribute, path }) => {
2214
2241
  if (isDynamicZoneAttribute(attribute)) {
2215
- throwInvalidParam({ key, path: path.attribute });
2242
+ throwInvalidKey({ key, path: path.attribute });
2216
2243
  }
2217
2244
  };
2218
2245
  const throwDisallowedFields = (allowedFields = null) => ({ key, path: { attribute: path } }) => {
@@ -2234,7 +2261,7 @@ const throwDisallowedFields = (allowedFields = null) => ({ key, path: { attribut
2234
2261
  if (isPathAllowed) {
2235
2262
  return;
2236
2263
  }
2237
- throwInvalidParam({ key, path });
2264
+ throwInvalidKey({ key, path });
2238
2265
  };
2239
2266
  const getContainedPaths = (path) => {
2240
2267
  const parts = toPath(path);
@@ -2244,7 +2271,7 @@ const getContainedPaths = (path) => {
2244
2271
  };
2245
2272
  const throwRestrictedFields = (restrictedFields = null) => ({ key, path: { attribute: path } }) => {
2246
2273
  if (restrictedFields === null) {
2247
- throwInvalidParam({ key, path });
2274
+ throwInvalidKey({ key, path });
2248
2275
  }
2249
2276
  if (!(isArray(restrictedFields) && restrictedFields.every(isString))) {
2250
2277
  throw new TypeError(
@@ -2252,14 +2279,44 @@ const throwRestrictedFields = (restrictedFields = null) => ({ key, path: { attri
2252
2279
  );
2253
2280
  }
2254
2281
  if (restrictedFields.includes(path)) {
2255
- throwInvalidParam({ key, path });
2282
+ throwInvalidKey({ key, path });
2256
2283
  }
2257
2284
  const isRestrictedNested = restrictedFields.some(
2258
2285
  (allowedPath) => path?.toString().startsWith(`${allowedPath}.`)
2259
2286
  );
2260
2287
  if (isRestrictedNested) {
2261
- throwInvalidParam({ key, path });
2288
+ throwInvalidKey({ key, path });
2289
+ }
2290
+ };
2291
+ const ID_FIELDS = [constants$1.DOC_ID_ATTRIBUTE, constants$1.DOC_ID_ATTRIBUTE];
2292
+ const ALLOWED_ROOT_LEVEL_FIELDS = [...ID_FIELDS];
2293
+ const MORPH_TO_ALLOWED_FIELDS = ["__type"];
2294
+ const DYNAMIC_ZONE_ALLOWED_FIELDS = ["__component"];
2295
+ const RELATION_REORDERING_FIELDS = ["connect", "disconnect", "set", "options"];
2296
+ const throwUnrecognizedFields = ({ key, attribute, path, schema, parent }) => {
2297
+ if (attribute) {
2298
+ return;
2299
+ }
2300
+ if (path.attribute === null) {
2301
+ if (ALLOWED_ROOT_LEVEL_FIELDS.includes(key)) {
2302
+ return;
2303
+ }
2304
+ return throwInvalidKey({ key, path: attribute });
2305
+ }
2306
+ if (isMorphToRelationalAttribute(parent?.attribute) && MORPH_TO_ALLOWED_FIELDS.includes(key)) {
2307
+ return;
2308
+ }
2309
+ if (isComponentSchema(schema) && isDynamicZoneAttribute(parent?.attribute) && DYNAMIC_ZONE_ALLOWED_FIELDS.includes(key)) {
2310
+ return;
2311
+ }
2312
+ if (hasRelationReordering(parent?.attribute) && RELATION_REORDERING_FIELDS.includes(key)) {
2313
+ return;
2314
+ }
2315
+ const canUseID = isRelationalAttribute(parent?.attribute) || isMediaAttribute(parent?.attribute);
2316
+ if (canUseID && !ID_FIELDS.includes(key)) {
2317
+ return;
2262
2318
  }
2319
+ throwInvalidKey({ key, path: attribute });
2263
2320
  };
2264
2321
  const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2265
2322
  __proto__: null,
@@ -2269,7 +2326,8 @@ const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
2269
2326
  throwPassword: visitor$3,
2270
2327
  throwPrivate: visitor$2,
2271
2328
  throwRestrictedFields,
2272
- throwRestrictedRelations
2329
+ throwRestrictedRelations,
2330
+ throwUnrecognizedFields
2273
2331
  }, Symbol.toStringTag, { value: "Module" }));
2274
2332
  const { ID_ATTRIBUTE: ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE: DOC_ID_ATTRIBUTE$1 } = constants$1;
2275
2333
  const throwPasswords = (ctx) => async (entity) => {
@@ -2290,7 +2348,7 @@ const defaultValidateFilters = curry((ctx, filters2) => {
2290
2348
  }
2291
2349
  const isAttribute = !!attribute;
2292
2350
  if (!isAttribute && !isOperator(key)) {
2293
- throwInvalidParam({ key, path: path.attribute });
2351
+ throwInvalidKey({ key, path: path.attribute });
2294
2352
  }
2295
2353
  }, ctx),
2296
2354
  // dynamic zones from filters
@@ -2315,7 +2373,7 @@ const defaultValidateSort = curry((ctx, sort2) => {
2315
2373
  return;
2316
2374
  }
2317
2375
  if (!attribute) {
2318
- throwInvalidParam({ key, path: path.attribute });
2376
+ throwInvalidKey({ key, path: path.attribute });
2319
2377
  }
2320
2378
  }, ctx),
2321
2379
  // dynamic zones from sort
@@ -2332,7 +2390,7 @@ const defaultValidateSort = curry((ctx, sort2) => {
2332
2390
  return;
2333
2391
  }
2334
2392
  if (!isScalarAttribute(attribute) && isEmpty(value)) {
2335
- throwInvalidParam({ key, path: path.attribute });
2393
+ throwInvalidKey({ key, path: path.attribute });
2336
2394
  }
2337
2395
  }, ctx)
2338
2396
  )(sort2);
@@ -2348,7 +2406,7 @@ const defaultValidateFields = curry((ctx, fields2) => {
2348
2406
  return;
2349
2407
  }
2350
2408
  if (isNil(attribute) || !isScalarAttribute(attribute)) {
2351
- throwInvalidParam({ key, path: path.attribute });
2409
+ throwInvalidKey({ key, path: path.attribute });
2352
2410
  }
2353
2411
  }, ctx),
2354
2412
  // private fields
@@ -2443,15 +2501,18 @@ const createAPIValidators = (opts) => {
2443
2501
  (data2) => {
2444
2502
  if (isObject(data2)) {
2445
2503
  if (ID_ATTRIBUTE in data2) {
2446
- throwInvalidParam({ key: ID_ATTRIBUTE });
2504
+ throwInvalidKey({ key: ID_ATTRIBUTE });
2447
2505
  }
2448
2506
  if (DOC_ID_ATTRIBUTE in data2) {
2449
- throwInvalidParam({ key: DOC_ID_ATTRIBUTE });
2507
+ throwInvalidKey({ key: DOC_ID_ATTRIBUTE });
2450
2508
  }
2451
2509
  }
2510
+ return data2;
2452
2511
  },
2453
2512
  // non-writable attributes
2454
- traverseEntity$1(throwRestrictedFields(nonWritableAttributes), { schema, getModel })
2513
+ traverseEntity$1(throwRestrictedFields(nonWritableAttributes), { schema, getModel }),
2514
+ // unrecognized attributes
2515
+ traverseEntity$1(throwUnrecognizedFields, { schema, getModel })
2455
2516
  ];
2456
2517
  if (auth) {
2457
2518
  transforms.push(
@@ -2462,7 +2523,14 @@ const createAPIValidators = (opts) => {
2462
2523
  );
2463
2524
  }
2464
2525
  opts?.validators?.input?.forEach((validator) => transforms.push(validator(schema)));
2465
- await pipe(...transforms)(data);
2526
+ try {
2527
+ await pipe(...transforms)(data);
2528
+ } catch (e) {
2529
+ if (e instanceof ValidationError) {
2530
+ e.details.source = "body";
2531
+ }
2532
+ throw e;
2533
+ }
2466
2534
  };
2467
2535
  const validateQuery = async (query, schema, { auth } = {}) => {
2468
2536
  if (!schema) {
@@ -2499,7 +2567,15 @@ const createAPIValidators = (opts) => {
2499
2567
  })
2500
2568
  );
2501
2569
  }
2502
- await pipe(...transforms)(filters2);
2570
+ try {
2571
+ await pipe(...transforms)(filters2);
2572
+ } catch (e) {
2573
+ if (e instanceof ValidationError) {
2574
+ e.details.source = "query";
2575
+ e.details.param = "filters";
2576
+ }
2577
+ throw e;
2578
+ }
2503
2579
  };
2504
2580
  const validateSort = async (sort2, schema, { auth } = {}) => {
2505
2581
  if (!schema) {
@@ -2514,14 +2590,30 @@ const createAPIValidators = (opts) => {
2514
2590
  })
2515
2591
  );
2516
2592
  }
2517
- await pipe(...transforms)(sort2);
2593
+ try {
2594
+ await pipe(...transforms)(sort2);
2595
+ } catch (e) {
2596
+ if (e instanceof ValidationError) {
2597
+ e.details.source = "query";
2598
+ e.details.param = "sort";
2599
+ }
2600
+ throw e;
2601
+ }
2518
2602
  };
2519
2603
  const validateFields = async (fields2, schema) => {
2520
2604
  if (!schema) {
2521
2605
  throw new Error("Missing schema in validateFields");
2522
2606
  }
2523
2607
  const transforms = [defaultValidateFields({ schema, getModel })];
2524
- await pipe(...transforms)(fields2);
2608
+ try {
2609
+ await pipe(...transforms)(fields2);
2610
+ } catch (e) {
2611
+ if (e instanceof ValidationError) {
2612
+ e.details.source = "query";
2613
+ e.details.param = "fields";
2614
+ }
2615
+ throw e;
2616
+ }
2525
2617
  };
2526
2618
  const validatePopulate = async (populate2, schema, { auth } = {}) => {
2527
2619
  if (!schema) {
@@ -2536,7 +2628,15 @@ const createAPIValidators = (opts) => {
2536
2628
  })
2537
2629
  );
2538
2630
  }
2539
- await pipe(...transforms)(populate2);
2631
+ try {
2632
+ await pipe(...transforms)(populate2);
2633
+ } catch (e) {
2634
+ if (e instanceof ValidationError) {
2635
+ e.details.source = "query";
2636
+ e.details.param = "populate";
2637
+ }
2638
+ throw e;
2639
+ }
2540
2640
  };
2541
2641
  return {
2542
2642
  input: validateInput,
@@ -2620,8 +2720,57 @@ const withDefaultPagination = (args, { defaults: defaults2 = {}, maxLimit = -1 }
2620
2720
  );
2621
2721
  return replacePaginationAttributes(args);
2622
2722
  };
2723
+ const transformPagedPaginationInfo = (paginationInfo, total) => {
2724
+ if (!isNil(paginationInfo.page)) {
2725
+ const page = paginationInfo.page;
2726
+ const pageSize = paginationInfo.pageSize ?? total;
2727
+ return {
2728
+ page,
2729
+ pageSize,
2730
+ pageCount: pageSize > 0 ? Math.ceil(total / pageSize) : 0,
2731
+ total
2732
+ };
2733
+ }
2734
+ if (!isNil(paginationInfo.start)) {
2735
+ const start = paginationInfo.start;
2736
+ const limit = paginationInfo.limit ?? total;
2737
+ return {
2738
+ page: Math.floor(start / limit) + 1,
2739
+ pageSize: limit,
2740
+ pageCount: limit > 0 ? Math.ceil(total / limit) : 0,
2741
+ total
2742
+ };
2743
+ }
2744
+ return {
2745
+ ...paginationInfo,
2746
+ page: 1,
2747
+ pageSize: 10,
2748
+ pageCount: 1,
2749
+ total
2750
+ };
2751
+ };
2752
+ const transformOffsetPaginationInfo = (paginationInfo, total) => {
2753
+ if (!isNil(paginationInfo.page)) {
2754
+ const limit = paginationInfo.pageSize ?? total;
2755
+ const start = (paginationInfo.page - 1) * limit;
2756
+ return { start, limit, total };
2757
+ }
2758
+ if (!isNil(paginationInfo.start)) {
2759
+ const start = paginationInfo.start;
2760
+ const limit = paginationInfo.limit ?? total;
2761
+ return { start, limit, total };
2762
+ }
2763
+ return {
2764
+ ...paginationInfo,
2765
+ start: 0,
2766
+ limit: 10,
2767
+ total
2768
+ };
2769
+ };
2623
2770
  const pagination = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2624
2771
  __proto__: null,
2772
+ transformOffsetPaginationInfo,
2773
+ transformPagedPaginationInfo,
2625
2774
  withDefaultPagination
2626
2775
  }, Symbol.toStringTag, { value: "Module" }));
2627
2776
  const SUPPORTED_PACKAGE_MANAGERS = ["npm", "yarn"];
@@ -2745,9 +2894,9 @@ const toRegressedEnumValue = (value) => slugify(value, {
2745
2894
  separator: "_"
2746
2895
  });
2747
2896
  const getCommonPath = (...paths) => {
2748
- const [segments, ...otherSegments] = paths.map((it) => _$1.split(it, "/"));
2749
- return _$1.join(
2750
- _$1.takeWhile(segments, (str, index2) => otherSegments.every((it) => it[index2] === str)),
2897
+ const [segments, ...otherSegments] = paths.map((it) => ___default.split(it, "/"));
2898
+ return ___default.join(
2899
+ ___default.takeWhile(segments, (str, index2) => otherSegments.every((it) => it[index2] === str)),
2751
2900
  "/"
2752
2901
  );
2753
2902
  };
@@ -2789,9 +2938,9 @@ const arrays = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
2789
2938
  __proto__: null,
2790
2939
  includesString
2791
2940
  }, Symbol.toStringTag, { value: "Module" }));
2792
- const keysDeep = (obj, path = []) => !_$1.isObject(obj) ? [path.join(".")] : _$1.reduce(
2941
+ const keysDeep = (obj, path = []) => !___default.isObject(obj) ? [path.join(".")] : ___default.reduce(
2793
2942
  obj,
2794
- (acc, next, key) => _$1.concat(acc, keysDeep(next, [...path, key])),
2943
+ (acc, next, key) => ___default.concat(acc, keysDeep(next, [...path, key])),
2795
2944
  []
2796
2945
  );
2797
2946
  const objects = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -2855,8 +3004,8 @@ function printValue(value, quoteStrings) {
2855
3004
  );
2856
3005
  }
2857
3006
  const strapiID = () => new StrapiIDSchema();
2858
- const isNotNilTest = (value) => !_$1.isNil(value);
2859
- const isNotNullTest = (value) => !_$1.isNull(value);
3007
+ const isNotNilTest = (value) => !___default.isNil(value);
3008
+ const isNotNullTest = (value) => !___default.isNull(value);
2860
3009
  yup$1.addMethod(yup$1.mixed, "notNil", function isNotNill(msg = "${path} must be defined.") {
2861
3010
  return this.test("defined", msg, isNotNilTest);
2862
3011
  });
@@ -2867,7 +3016,7 @@ yup$1.addMethod(yup$1.mixed, "isFunction", function isFunction(message = "${path
2867
3016
  return this.test(
2868
3017
  "is a function",
2869
3018
  message,
2870
- (value) => _$1.isUndefined(value) || _$1.isFunction(value)
3019
+ (value) => ___default.isUndefined(value) || ___default.isFunction(value)
2871
3020
  );
2872
3021
  });
2873
3022
  yup$1.addMethod(
@@ -2899,7 +3048,7 @@ yup$1.addMethod(
2899
3048
  return this.test(
2900
3049
  "only contains functions",
2901
3050
  message,
2902
- (value) => _$1.isUndefined(value) || value && Object.values(value).every(_$1.isFunction)
3051
+ (value) => ___default.isUndefined(value) || value && Object.values(value).every(___default.isFunction)
2903
3052
  );
2904
3053
  }
2905
3054
  );
@@ -2974,6 +3123,27 @@ const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
2974
3123
  isManyToAny,
2975
3124
  isOneToAny
2976
3125
  }, Symbol.toStringTag, { value: "Module" }));
3126
+ const validateZod = (schema) => (data) => {
3127
+ try {
3128
+ return schema.parse(data);
3129
+ } catch (error) {
3130
+ if (error instanceof z.ZodError) {
3131
+ const { message, errors: errors2 } = formatZodErrors(error);
3132
+ throw new ValidationError(message, { errors: errors2 });
3133
+ }
3134
+ throw error;
3135
+ }
3136
+ };
3137
+ const formatZodErrors = (zodError) => ({
3138
+ errors: zodError.errors.map((error) => {
3139
+ return {
3140
+ path: error.path,
3141
+ message: error.message,
3142
+ name: "ValidationError"
3143
+ };
3144
+ }),
3145
+ message: "Validation error"
3146
+ });
2977
3147
  export {
2978
3148
  arrays,
2979
3149
  async,
@@ -3004,6 +3174,7 @@ export {
3004
3174
  index as validate,
3005
3175
  validateYupSchema,
3006
3176
  validateYupSchemaSync,
3177
+ validateZod,
3007
3178
  yup
3008
3179
  };
3009
3180
  //# sourceMappingURL=index.mjs.map