@strapi/utils 5.36.0 → 5.37.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 (72) hide show
  1. package/dist/content-api-constants.d.ts +17 -0
  2. package/dist/content-api-constants.d.ts.map +1 -0
  3. package/dist/content-api-constants.js +43 -0
  4. package/dist/content-api-constants.js.map +1 -0
  5. package/dist/content-api-constants.mjs +39 -0
  6. package/dist/content-api-constants.mjs.map +1 -0
  7. package/dist/content-api-route-params.d.ts +17 -0
  8. package/dist/content-api-route-params.d.ts.map +1 -0
  9. package/dist/content-api-route-params.js +21 -0
  10. package/dist/content-api-route-params.js.map +1 -0
  11. package/dist/content-api-route-params.mjs +18 -0
  12. package/dist/content-api-route-params.mjs.map +1 -0
  13. package/dist/content-types.d.ts +10 -2
  14. package/dist/content-types.d.ts.map +1 -1
  15. package/dist/content-types.js +22 -2
  16. package/dist/content-types.js.map +1 -1
  17. package/dist/content-types.mjs +19 -3
  18. package/dist/content-types.mjs.map +1 -1
  19. package/dist/convert-query-params.d.ts +5 -0
  20. package/dist/convert-query-params.d.ts.map +1 -1
  21. package/dist/convert-query-params.js +5 -4
  22. package/dist/convert-query-params.js.map +1 -1
  23. package/dist/convert-query-params.mjs +5 -4
  24. package/dist/convert-query-params.mjs.map +1 -1
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +9 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +2 -0
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/sanitize/index.d.ts +15 -1
  32. package/dist/sanitize/index.d.ts.map +1 -1
  33. package/dist/sanitize/index.js +73 -3
  34. package/dist/sanitize/index.js.map +1 -1
  35. package/dist/sanitize/index.mjs +74 -4
  36. package/dist/sanitize/index.mjs.map +1 -1
  37. package/dist/sanitize/visitors/index.d.ts +1 -0
  38. package/dist/sanitize/visitors/index.d.ts.map +1 -1
  39. package/dist/sanitize/visitors/index.js +2 -0
  40. package/dist/sanitize/visitors/index.js.map +1 -1
  41. package/dist/sanitize/visitors/index.mjs +1 -0
  42. package/dist/sanitize/visitors/index.mjs.map +1 -1
  43. package/dist/sanitize/visitors/remove-unrecognized-fields.d.ts +4 -0
  44. package/dist/sanitize/visitors/remove-unrecognized-fields.d.ts.map +1 -0
  45. package/dist/sanitize/visitors/remove-unrecognized-fields.js +43 -0
  46. package/dist/sanitize/visitors/remove-unrecognized-fields.js.map +1 -0
  47. package/dist/sanitize/visitors/remove-unrecognized-fields.mjs +41 -0
  48. package/dist/sanitize/visitors/remove-unrecognized-fields.mjs.map +1 -0
  49. package/dist/traverse-entity.d.ts +4 -0
  50. package/dist/traverse-entity.d.ts.map +1 -1
  51. package/dist/traverse-entity.js +13 -7
  52. package/dist/traverse-entity.js.map +1 -1
  53. package/dist/traverse-entity.mjs +13 -7
  54. package/dist/traverse-entity.mjs.map +1 -1
  55. package/dist/validate/index.d.ts +14 -1
  56. package/dist/validate/index.d.ts.map +1 -1
  57. package/dist/validate/index.js +83 -7
  58. package/dist/validate/index.js.map +1 -1
  59. package/dist/validate/index.mjs +83 -7
  60. package/dist/validate/index.mjs.map +1 -1
  61. package/dist/validate/validators.js +0 -1
  62. package/dist/validate/validators.js.map +1 -1
  63. package/dist/validate/validators.mjs +0 -1
  64. package/dist/validate/validators.mjs.map +1 -1
  65. package/dist/validate/visitors/throw-unrecognized-fields.d.ts.map +1 -1
  66. package/dist/validate/visitors/throw-unrecognized-fields.js +16 -32
  67. package/dist/validate/visitors/throw-unrecognized-fields.js.map +1 -1
  68. package/dist/validate/visitors/throw-unrecognized-fields.mjs +17 -33
  69. package/dist/validate/visitors/throw-unrecognized-fields.mjs.map +1 -1
  70. package/dist/zod-schema.d.ts +17 -0
  71. package/dist/zod-schema.d.ts.map +1 -0
  72. package/package.json +5 -5
@@ -1,62 +1,46 @@
1
- import { constants, isMorphToRelationalAttribute, isComponentSchema, isDynamicZoneAttribute, hasRelationReordering, isRelationalAttribute, isMediaAttribute } from '../../content-types.mjs';
1
+ import { ID_FIELDS, isMorphToRelationalAttribute, MORPH_TO_KEYS, isComponentSchema, isDynamicZoneAttribute, DYNAMIC_ZONE_KEYS, isRelationalAttribute, isMediaAttribute, RELATION_OPERATION_KEYS, isComponentAttribute } from '../../content-types.mjs';
2
2
  import { throwInvalidKey } from '../utils.mjs';
3
3
 
4
- // TODO these should all be centralized somewhere instead of maintaining a list
5
- const ID_FIELDS = [
6
- constants.DOC_ID_ATTRIBUTE,
7
- constants.DOC_ID_ATTRIBUTE
8
- ];
9
- const ALLOWED_ROOT_LEVEL_FIELDS = [
10
- ...ID_FIELDS
11
- ];
12
- const MORPH_TO_ALLOWED_FIELDS = [
13
- '__type'
14
- ];
15
- const DYNAMIC_ZONE_ALLOWED_FIELDS = [
16
- '__component'
17
- ];
18
- const RELATION_REORDERING_FIELDS = [
19
- 'connect',
20
- 'disconnect',
21
- 'set',
22
- 'options'
23
- ];
24
- const throwUnrecognizedFields = ({ key, attribute, path, schema, parent })=>{
4
+ const throwUnrecognizedFields = ({ key, attribute, path, schema, parent, allowedExtraRootKeys }, // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Visitor type requires second param
5
+ _visitorUtils)=>{
25
6
  // We only look at properties that are not attributes
26
7
  if (attribute) {
27
8
  return;
28
9
  }
29
- // At root level (path.attribute === null), only accept allowed fields
10
+ // At root level (path.attribute === null), only accept id-like fields
30
11
  if (path.attribute === null) {
31
- if (ALLOWED_ROOT_LEVEL_FIELDS.includes(key)) {
12
+ if (ID_FIELDS.includes(key)) {
13
+ return;
14
+ }
15
+ if (allowedExtraRootKeys?.includes(key)) {
32
16
  return;
33
17
  }
34
18
  return throwInvalidKey({
35
19
  key,
36
- path: attribute
20
+ path: path.attribute
37
21
  });
38
22
  }
39
23
  // allow special morphTo keys
40
- if (isMorphToRelationalAttribute(parent?.attribute) && MORPH_TO_ALLOWED_FIELDS.includes(key)) {
24
+ if (isMorphToRelationalAttribute(parent?.attribute) && MORPH_TO_KEYS.includes(key)) {
41
25
  return;
42
26
  }
43
27
  // allow special dz keys
44
- if (isComponentSchema(schema) && isDynamicZoneAttribute(parent?.attribute) && DYNAMIC_ZONE_ALLOWED_FIELDS.includes(key)) {
28
+ if (isComponentSchema(schema) && isDynamicZoneAttribute(parent?.attribute) && DYNAMIC_ZONE_KEYS.includes(key)) {
45
29
  return;
46
30
  }
47
- // allow special relation reordering keys in manyToX and XtoMany relations
48
- if (hasRelationReordering(parent?.attribute) && RELATION_REORDERING_FIELDS.includes(key)) {
31
+ // allow relation operation keys (connect, disconnect, set, options) for relations and media
32
+ if ((isRelationalAttribute(parent?.attribute) || isMediaAttribute(parent?.attribute)) && RELATION_OPERATION_KEYS.includes(key)) {
49
33
  return;
50
34
  }
51
- // allow id fields where it is needed for setting a relational id rather than trying to create with a given id
52
- const canUseID = isRelationalAttribute(parent?.attribute) || isMediaAttribute(parent?.attribute);
53
- if (canUseID && !ID_FIELDS.includes(key)) {
35
+ // allow id fields for relations, media, and components
36
+ const canUseID = isRelationalAttribute(parent?.attribute) || isMediaAttribute(parent?.attribute) || isComponentAttribute(parent?.attribute);
37
+ if (canUseID && ID_FIELDS.includes(key)) {
54
38
  return;
55
39
  }
56
40
  // if we couldn't find any reason for it to be here, throw
57
41
  throwInvalidKey({
58
42
  key,
59
- path: attribute
43
+ path: path.attribute
60
44
  });
61
45
  };
62
46
 
@@ -1 +1 @@
1
- {"version":3,"file":"throw-unrecognized-fields.mjs","sources":["../../../src/validate/visitors/throw-unrecognized-fields.ts"],"sourcesContent":["import {\n isDynamicZoneAttribute,\n isMorphToRelationalAttribute,\n isRelationalAttribute,\n constants,\n isComponentSchema,\n isMediaAttribute,\n hasRelationReordering,\n} from '../../content-types';\nimport type { Visitor } from '../../traverse-entity';\nimport { throwInvalidKey } from '../utils';\n\n// TODO these should all be centralized somewhere instead of maintaining a list\nconst ID_FIELDS = [constants.DOC_ID_ATTRIBUTE, constants.DOC_ID_ATTRIBUTE];\nconst ALLOWED_ROOT_LEVEL_FIELDS = [...ID_FIELDS];\nconst MORPH_TO_ALLOWED_FIELDS = ['__type'];\nconst DYNAMIC_ZONE_ALLOWED_FIELDS = ['__component'];\nconst RELATION_REORDERING_FIELDS = ['connect', 'disconnect', 'set', 'options'];\n\nconst throwUnrecognizedFields: Visitor = ({ key, attribute, path, schema, parent }) => {\n // We only look at properties that are not attributes\n if (attribute) {\n return;\n }\n\n // At root level (path.attribute === null), only accept allowed fields\n if (path.attribute === null) {\n if (ALLOWED_ROOT_LEVEL_FIELDS.includes(key)) {\n return;\n }\n\n return throwInvalidKey({ key, path: attribute });\n }\n\n // allow special morphTo keys\n if (isMorphToRelationalAttribute(parent?.attribute) && MORPH_TO_ALLOWED_FIELDS.includes(key)) {\n return;\n }\n\n // allow special dz keys\n if (\n isComponentSchema(schema) &&\n isDynamicZoneAttribute(parent?.attribute) &&\n DYNAMIC_ZONE_ALLOWED_FIELDS.includes(key)\n ) {\n return;\n }\n\n // allow special relation reordering keys in manyToX and XtoMany relations\n if (hasRelationReordering(parent?.attribute) && RELATION_REORDERING_FIELDS.includes(key)) {\n return;\n }\n\n // allow id fields where it is needed for setting a relational id rather than trying to create with a given id\n const canUseID = isRelationalAttribute(parent?.attribute) || isMediaAttribute(parent?.attribute);\n if (canUseID && !ID_FIELDS.includes(key)) {\n return;\n }\n\n // if we couldn't find any reason for it to be here, throw\n throwInvalidKey({ key, path: attribute });\n};\n\nexport default throwUnrecognizedFields;\n"],"names":["ID_FIELDS","constants","DOC_ID_ATTRIBUTE","ALLOWED_ROOT_LEVEL_FIELDS","MORPH_TO_ALLOWED_FIELDS","DYNAMIC_ZONE_ALLOWED_FIELDS","RELATION_REORDERING_FIELDS","throwUnrecognizedFields","key","attribute","path","schema","parent","includes","throwInvalidKey","isMorphToRelationalAttribute","isComponentSchema","isDynamicZoneAttribute","hasRelationReordering","canUseID","isRelationalAttribute","isMediaAttribute"],"mappings":";;;AAYA;AACA,MAAMA,SAAY,GAAA;AAACC,IAAAA,SAAAA,CAAUC,gBAAgB;AAAED,IAAAA,SAAAA,CAAUC;AAAiB,CAAA;AAC1E,MAAMC,yBAA4B,GAAA;AAAIH,IAAAA,GAAAA;AAAU,CAAA;AAChD,MAAMI,uBAA0B,GAAA;AAAC,IAAA;AAAS,CAAA;AAC1C,MAAMC,2BAA8B,GAAA;AAAC,IAAA;AAAc,CAAA;AACnD,MAAMC,0BAA6B,GAAA;AAAC,IAAA,SAAA;AAAW,IAAA,YAAA;AAAc,IAAA,KAAA;AAAO,IAAA;AAAU,CAAA;AAE9E,MAAMC,uBAAmC,GAAA,CAAC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAEC,MAAM,EAAEC,MAAM,EAAE,GAAA;;AAEhF,IAAA,IAAIH,SAAW,EAAA;AACb,QAAA;AACF;;IAGA,IAAIC,IAAAA,CAAKD,SAAS,KAAK,IAAM,EAAA;QAC3B,IAAIN,yBAAAA,CAA0BU,QAAQ,CAACL,GAAM,CAAA,EAAA;AAC3C,YAAA;AACF;AAEA,QAAA,OAAOM,eAAgB,CAAA;AAAEN,YAAAA,GAAAA;YAAKE,IAAMD,EAAAA;AAAU,SAAA,CAAA;AAChD;;AAGA,IAAA,IAAIM,6BAA6BH,MAAQH,EAAAA,SAAAA,CAAAA,IAAcL,uBAAwBS,CAAAA,QAAQ,CAACL,GAAM,CAAA,EAAA;AAC5F,QAAA;AACF;;IAGA,IACEQ,iBAAAA,CAAkBL,WAClBM,sBAAuBL,CAAAA,MAAAA,EAAQH,cAC/BJ,2BAA4BQ,CAAAA,QAAQ,CAACL,GACrC,CAAA,EAAA;AACA,QAAA;AACF;;AAGA,IAAA,IAAIU,sBAAsBN,MAAQH,EAAAA,SAAAA,CAAAA,IAAcH,0BAA2BO,CAAAA,QAAQ,CAACL,GAAM,CAAA,EAAA;AACxF,QAAA;AACF;;AAGA,IAAA,MAAMW,QAAWC,GAAAA,qBAAAA,CAAsBR,MAAQH,EAAAA,SAAAA,CAAAA,IAAcY,iBAAiBT,MAAQH,EAAAA,SAAAA,CAAAA;AACtF,IAAA,IAAIU,QAAY,IAAA,CAACnB,SAAUa,CAAAA,QAAQ,CAACL,GAAM,CAAA,EAAA;AACxC,QAAA;AACF;;IAGAM,eAAgB,CAAA;AAAEN,QAAAA,GAAAA;QAAKE,IAAMD,EAAAA;AAAU,KAAA,CAAA;AACzC;;;;"}
1
+ {"version":3,"file":"throw-unrecognized-fields.mjs","sources":["../../../src/validate/visitors/throw-unrecognized-fields.ts"],"sourcesContent":["import {\n isDynamicZoneAttribute,\n isMorphToRelationalAttribute,\n isRelationalAttribute,\n isComponentSchema,\n isMediaAttribute,\n isComponentAttribute,\n DYNAMIC_ZONE_KEYS,\n ID_FIELDS,\n MORPH_TO_KEYS,\n RELATION_OPERATION_KEYS,\n} from '../../content-types';\nimport type { Visitor } from '../../traverse-entity';\nimport { throwInvalidKey } from '../utils';\n\nconst throwUnrecognizedFields: Visitor = (\n { key, attribute, path, schema, parent, allowedExtraRootKeys },\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- Visitor type requires second param\n _visitorUtils\n) => {\n // We only look at properties that are not attributes\n if (attribute) {\n return;\n }\n\n // At root level (path.attribute === null), only accept id-like fields\n if (path.attribute === null) {\n if (ID_FIELDS.includes(key)) {\n return;\n }\n if (allowedExtraRootKeys?.includes(key)) {\n return;\n }\n\n return throwInvalidKey({ key, path: path.attribute });\n }\n\n // allow special morphTo keys\n if (isMorphToRelationalAttribute(parent?.attribute) && MORPH_TO_KEYS.includes(key)) {\n return;\n }\n\n // allow special dz keys\n if (\n isComponentSchema(schema) &&\n isDynamicZoneAttribute(parent?.attribute) &&\n DYNAMIC_ZONE_KEYS.includes(key)\n ) {\n return;\n }\n\n // allow relation operation keys (connect, disconnect, set, options) for relations and media\n if (\n (isRelationalAttribute(parent?.attribute) || isMediaAttribute(parent?.attribute)) &&\n RELATION_OPERATION_KEYS.includes(key)\n ) {\n return;\n }\n\n // allow id fields for relations, media, and components\n const canUseID =\n isRelationalAttribute(parent?.attribute) ||\n isMediaAttribute(parent?.attribute) ||\n isComponentAttribute(parent?.attribute);\n if (canUseID && ID_FIELDS.includes(key)) {\n return;\n }\n\n // if we couldn't find any reason for it to be here, throw\n throwInvalidKey({ key, path: path.attribute });\n};\n\nexport default throwUnrecognizedFields;\n"],"names":["throwUnrecognizedFields","key","attribute","path","schema","parent","allowedExtraRootKeys","_visitorUtils","ID_FIELDS","includes","throwInvalidKey","isMorphToRelationalAttribute","MORPH_TO_KEYS","isComponentSchema","isDynamicZoneAttribute","DYNAMIC_ZONE_KEYS","isRelationalAttribute","isMediaAttribute","RELATION_OPERATION_KEYS","canUseID","isComponentAttribute"],"mappings":";;;AAeA,MAAMA,0BAAmC,CACvC,EAAEC,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAEC,MAAM,EAAEC,MAAM,EAAEC,oBAAoB,EAAE;AAE9DC,aAAAA,GAAAA;;AAGA,IAAA,IAAIL,SAAW,EAAA;AACb,QAAA;AACF;;IAGA,IAAIC,IAAAA,CAAKD,SAAS,KAAK,IAAM,EAAA;QAC3B,IAAIM,SAAAA,CAAUC,QAAQ,CAACR,GAAM,CAAA,EAAA;AAC3B,YAAA;AACF;QACA,IAAIK,oBAAAA,EAAsBG,SAASR,GAAM,CAAA,EAAA;AACvC,YAAA;AACF;AAEA,QAAA,OAAOS,eAAgB,CAAA;AAAET,YAAAA,GAAAA;AAAKE,YAAAA,IAAAA,EAAMA,KAAKD;AAAU,SAAA,CAAA;AACrD;;AAGA,IAAA,IAAIS,6BAA6BN,MAAQH,EAAAA,SAAAA,CAAAA,IAAcU,aAAcH,CAAAA,QAAQ,CAACR,GAAM,CAAA,EAAA;AAClF,QAAA;AACF;;IAGA,IACEY,iBAAAA,CAAkBT,WAClBU,sBAAuBT,CAAAA,MAAAA,EAAQH,cAC/Ba,iBAAkBN,CAAAA,QAAQ,CAACR,GAC3B,CAAA,EAAA;AACA,QAAA;AACF;;AAGA,IAAA,IACE,CAACe,qBAAsBX,CAAAA,MAAAA,EAAQH,SAAce,CAAAA,IAAAA,gBAAAA,CAAiBZ,MAAQH,EAAAA,SAAAA,CAAS,KAC/EgB,uBAAAA,CAAwBT,QAAQ,CAACR,GACjC,CAAA,EAAA;AACA,QAAA;AACF;;IAGA,MAAMkB,QAAAA,GACJH,sBAAsBX,MAAQH,EAAAA,SAAAA,CAAAA,IAC9Be,iBAAiBZ,MAAQH,EAAAA,SAAAA,CAAAA,IACzBkB,qBAAqBf,MAAQH,EAAAA,SAAAA,CAAAA;AAC/B,IAAA,IAAIiB,QAAYX,IAAAA,SAAAA,CAAUC,QAAQ,CAACR,GAAM,CAAA,EAAA;AACvC,QAAA;AACF;;IAGAS,eAAgB,CAAA;AAAET,QAAAA,GAAAA;AAAKE,QAAAA,IAAAA,EAAMA,KAAKD;AAAU,KAAA,CAAA;AAC9C;;;;"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Re-export of the Zod v4 schema builder from the same version Strapi uses
3
+ * internally. Use this for building schemas passed to content API param
4
+ * registration (addQueryParams / addInputParams) so your code stays compatible
5
+ * across Strapi minor/patch updates.
6
+ *
7
+ * @example
8
+ * import { z } from '@strapi/utils';
9
+ * strapi.contentAPI.addQueryParams({
10
+ * search: {
11
+ * schema: z.string().max(200).optional(),
12
+ * matchRoute: (route) => route.path.includes('articles'),
13
+ * },
14
+ * });
15
+ */
16
+ export { z } from 'zod/v4';
17
+ //# sourceMappingURL=zod-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-schema.d.ts","sourceRoot":"","sources":["../src/zod-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/utils",
3
- "version": "5.36.0",
3
+ "version": "5.37.0",
4
4
  "description": "Shared utilities for the Strapi packages",
5
5
  "keywords": [
6
6
  "strapi",
@@ -50,10 +50,10 @@
50
50
  "date-fns": "2.30.0",
51
51
  "execa": "5.1.1",
52
52
  "http-errors": "2.0.0",
53
- "lodash": "4.17.21",
53
+ "lodash": "4.17.23",
54
54
  "node-machine-id": "1.1.12",
55
55
  "p-map": "4.0.0",
56
- "preferred-pm": "3.1.2",
56
+ "preferred-pm": "3.1.3",
57
57
  "yup": "0.32.9",
58
58
  "zod": "3.25.67"
59
59
  },
@@ -61,10 +61,10 @@
61
61
  "@types/http-errors": "2.0.4",
62
62
  "@types/koa": "2.13.4",
63
63
  "@types/node": "24.10.0",
64
- "eslint-config-custom": "5.36.0",
64
+ "eslint-config-custom": "5.37.0",
65
65
  "koa": "2.16.3",
66
66
  "koa-body": "6.0.1",
67
- "tsconfig": "5.36.0"
67
+ "tsconfig": "5.37.0"
68
68
  },
69
69
  "engines": {
70
70
  "node": ">=20.0.0 <=24.x.x",