@strapi/utils 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 (60) hide show
  1. package/dist/async.d.ts +9 -6
  2. package/dist/async.d.ts.map +1 -1
  3. package/dist/content-types.d.ts +2 -4
  4. package/dist/content-types.d.ts.map +1 -1
  5. package/dist/convert-query-params.d.ts +11 -8
  6. package/dist/convert-query-params.d.ts.map +1 -1
  7. package/dist/env-helper.d.ts +3 -1
  8. package/dist/env-helper.d.ts.map +1 -1
  9. package/dist/index.d.ts +25 -33
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1444 -1444
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +1450 -1452
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/machine-id.d.ts +3 -0
  16. package/dist/machine-id.d.ts.map +1 -0
  17. package/dist/package-manager.d.ts +7 -0
  18. package/dist/package-manager.d.ts.map +1 -0
  19. package/dist/primitives/arrays.d.ts +3 -0
  20. package/dist/primitives/arrays.d.ts.map +1 -0
  21. package/dist/primitives/dates.d.ts +3 -0
  22. package/dist/primitives/dates.d.ts.map +1 -0
  23. package/dist/primitives/index.d.ts +5 -0
  24. package/dist/primitives/index.d.ts.map +1 -0
  25. package/dist/primitives/objects.d.ts +3 -0
  26. package/dist/primitives/objects.d.ts.map +1 -0
  27. package/dist/{string-formatting.d.ts → primitives/strings.d.ts} +3 -6
  28. package/dist/primitives/strings.d.ts.map +1 -0
  29. package/dist/sanitize/index.d.ts.map +1 -1
  30. package/dist/sanitize/sanitizers.d.ts.map +1 -1
  31. package/dist/sanitize/visitors/expand-wildcard-populate.d.ts +4 -0
  32. package/dist/sanitize/visitors/expand-wildcard-populate.d.ts.map +1 -0
  33. package/dist/sanitize/visitors/index.d.ts +1 -0
  34. package/dist/sanitize/visitors/index.d.ts.map +1 -1
  35. package/dist/traverse/factory.d.ts +1 -1
  36. package/dist/traverse/query-populate.d.ts.map +1 -1
  37. package/dist/types.d.ts +1 -4
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/validate/index.d.ts +1 -0
  40. package/dist/validate/index.d.ts.map +1 -1
  41. package/dist/validate/utils.d.ts +2 -1
  42. package/dist/validate/utils.d.ts.map +1 -1
  43. package/dist/validate/validators.d.ts +2 -1
  44. package/dist/validate/validators.d.ts.map +1 -1
  45. package/dist/yup.d.ts +0 -1
  46. package/dist/yup.d.ts.map +1 -1
  47. package/package.json +10 -8
  48. package/dist/code-generator.d.ts +0 -3
  49. package/dist/code-generator.d.ts.map +0 -1
  50. package/dist/config.d.ts +0 -9
  51. package/dist/config.d.ts.map +0 -1
  52. package/dist/object-formatting.d.ts +0 -4
  53. package/dist/object-formatting.d.ts.map +0 -1
  54. package/dist/parse-multipart.d.ts +0 -7
  55. package/dist/parse-multipart.d.ts.map +0 -1
  56. package/dist/string-formatting.d.ts.map +0 -1
  57. package/dist/template-configuration.d.ts +0 -6
  58. package/dist/template-configuration.d.ts.map +0 -1
  59. package/dist/webhook.d.ts +0 -6
  60. package/dist/webhook.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -2,11 +2,15 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const _$1 = require("lodash");
4
4
  const fp = require("lodash/fp");
5
- const yup$1 = require("yup");
6
- const httpErrors = require("http-errors");
7
- const slugify = require("@sindresorhus/slugify");
8
5
  const pMap = require("p-map");
6
+ const httpErrors = require("http-errors");
7
+ const crypto = require("crypto");
8
+ const nodeMachineId = require("node-machine-id");
9
+ const yup$1 = require("yup");
10
+ const execa = require("execa");
11
+ const preferredPM = require("preferred-pm");
9
12
  const node_stream = require("node:stream");
13
+ const slugify = require("@sindresorhus/slugify");
10
14
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
11
15
  function _interopNamespace(e) {
12
16
  if (e && e.__esModule)
@@ -46,56 +50,25 @@ function _mergeNamespaces(n, m) {
46
50
  return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }));
47
51
  }
48
52
  const ___default = /* @__PURE__ */ _interopDefault(_$1);
53
+ const pMap__default = /* @__PURE__ */ _interopDefault(pMap);
49
54
  const yup__namespace = /* @__PURE__ */ _interopNamespace(yup$1);
55
+ const execa__default = /* @__PURE__ */ _interopDefault(execa);
56
+ const preferredPM__default = /* @__PURE__ */ _interopDefault(preferredPM);
50
57
  const slugify__default = /* @__PURE__ */ _interopDefault(slugify);
51
- const pMap__default = /* @__PURE__ */ _interopDefault(pMap);
52
- const parseMultipartData = (ctx) => {
53
- if (!ctx.is("multipart")) {
54
- return { data: ctx.request.body, files: {} };
55
- }
56
- const { body = {}, files = {} } = ctx.request;
57
- if (!body.data) {
58
- return ctx.badRequest(
59
- `When using multipart/form-data you need to provide your data in a JSON 'data' field.`
60
- );
61
- }
62
- let data;
63
- try {
64
- data = JSON.parse(body.data);
65
- } catch (error) {
66
- return ctx.badRequest(`Invalid 'data' field. 'data' should be a valid JSON.`);
67
- }
68
- const filesToUpload = Object.keys(files).reduce((acc2, key2) => {
69
- const fullPath = ___default.default.toPath(key2);
70
- if (fullPath.length <= 1 || fullPath[0] !== "files") {
71
- return ctx.badRequest(
72
- `When using multipart/form-data you need to provide your files by prefixing them with the 'files'.
73
- For example, when a media file is named "avatar", make sure the form key name is "files.avatar"`
74
- );
75
- }
76
- const path = ___default.default.tail(fullPath);
77
- acc2[path.join(".")] = files[key2];
78
- return acc2;
79
- }, {});
80
- return {
81
- data,
82
- files: filesToUpload
83
- };
84
- };
85
58
  const _ = require("lodash");
86
- const dates = require("date-fns");
59
+ const dates$1 = require("date-fns");
87
60
  const timeRegex = /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$/;
88
61
  const isDate = (v) => {
89
- return dates.isDate(v);
62
+ return dates$1.isDate(v);
90
63
  };
91
- const parseTime = (value2) => {
92
- if (isDate(value2)) {
93
- return dates.format(value2, "HH:mm:ss.SSS");
64
+ const parseTime = (value) => {
65
+ if (isDate(value)) {
66
+ return dates$1.format(value, "HH:mm:ss.SSS");
94
67
  }
95
- if (typeof value2 !== "string") {
96
- throw new Error(`Expected a string, got a ${typeof value2}`);
68
+ if (typeof value !== "string") {
69
+ throw new Error(`Expected a string, got a ${typeof value}`);
97
70
  }
98
- const result = value2.match(timeRegex);
71
+ const result = value.match(timeRegex);
99
72
  if (result === null) {
100
73
  throw new Error("Invalid time format, expected HH:mm:ss.SSS");
101
74
  }
@@ -103,721 +76,289 @@ const parseTime = (value2) => {
103
76
  const fractionPart = _.padEnd(fraction.slice(1), 3, "0");
104
77
  return `${hours}:${minutes}:${seconds}.${fractionPart}`;
105
78
  };
106
- const parseDate = (value2) => {
107
- if (isDate(value2)) {
108
- return dates.format(value2, "yyyy-MM-dd");
79
+ const parseDate = (value) => {
80
+ if (isDate(value)) {
81
+ return dates$1.format(value, "yyyy-MM-dd");
109
82
  }
110
- if (typeof value2 !== "string") {
111
- throw new Error(`Expected a string, got a ${typeof value2}`);
83
+ if (typeof value !== "string") {
84
+ throw new Error(`Expected a string, got a ${typeof value}`);
112
85
  }
113
86
  try {
114
- const date = dates.parseISO(value2);
115
- if (dates.isValid(date))
116
- return dates.format(date, "yyyy-MM-dd");
87
+ const date = dates$1.parseISO(value);
88
+ if (dates$1.isValid(date))
89
+ return dates$1.format(date, "yyyy-MM-dd");
117
90
  throw new Error(`Invalid format, expected an ISO compatible date`);
118
91
  } catch (error) {
119
92
  throw new Error(`Invalid format, expected an ISO compatible date`);
120
93
  }
121
94
  };
122
- const parseDateTimeOrTimestamp = (value2) => {
123
- if (isDate(value2)) {
124
- return value2;
95
+ const parseDateTimeOrTimestamp = (value) => {
96
+ if (isDate(value)) {
97
+ return value;
125
98
  }
126
- if (typeof value2 !== "string") {
127
- throw new Error(`Expected a string, got a ${typeof value2}`);
99
+ if (typeof value !== "string") {
100
+ throw new Error(`Expected a string, got a ${typeof value}`);
128
101
  }
129
102
  try {
130
- const date = dates.parseISO(value2);
131
- if (dates.isValid(date))
103
+ const date = dates$1.parseISO(value);
104
+ if (dates$1.isValid(date))
132
105
  return date;
133
- const milliUnixDate = dates.parse(value2, "T", /* @__PURE__ */ new Date());
134
- if (dates.isValid(milliUnixDate))
106
+ const milliUnixDate = dates$1.parse(value, "T", /* @__PURE__ */ new Date());
107
+ if (dates$1.isValid(milliUnixDate))
135
108
  return milliUnixDate;
136
109
  throw new Error(`Invalid format, expected a timestamp or an ISO date`);
137
110
  } catch (error) {
138
111
  throw new Error(`Invalid format, expected a timestamp or an ISO date`);
139
112
  }
140
113
  };
141
- const parseBoolean = (value2, options) => {
114
+ const parseBoolean = (value, options) => {
142
115
  const { forceCast = false } = options;
143
- if (typeof value2 === "boolean") {
144
- return value2;
116
+ if (typeof value === "boolean") {
117
+ return value;
145
118
  }
146
- if (typeof value2 === "string" || typeof value2 === "number") {
147
- if (["true", "t", "1", 1].includes(value2)) {
119
+ if (typeof value === "string" || typeof value === "number") {
120
+ if (["true", "t", "1", 1].includes(value)) {
148
121
  return true;
149
122
  }
150
- if (["false", "f", "0", 0].includes(value2)) {
123
+ if (["false", "f", "0", 0].includes(value)) {
151
124
  return false;
152
125
  }
153
126
  }
154
127
  if (forceCast) {
155
- return Boolean(value2);
128
+ return Boolean(value);
156
129
  }
157
130
  throw new Error('Invalid boolean input. Expected "t","1","true","false","0","f"');
158
131
  };
159
132
  const parseType = (options) => {
160
- const { type, value: value2, forceCast } = options;
133
+ const { type, value, forceCast } = options;
161
134
  switch (type) {
162
135
  case "boolean":
163
- return parseBoolean(value2, { forceCast });
136
+ return parseBoolean(value, { forceCast });
164
137
  case "integer":
165
138
  case "biginteger":
166
139
  case "float":
167
140
  case "decimal": {
168
- return _.toNumber(value2);
141
+ return _.toNumber(value);
169
142
  }
170
143
  case "time": {
171
- return parseTime(value2);
144
+ return parseTime(value);
172
145
  }
173
146
  case "date": {
174
- return parseDate(value2);
147
+ return parseDate(value);
175
148
  }
176
149
  case "timestamp":
177
150
  case "datetime": {
178
- return parseDateTimeOrTimestamp(value2);
151
+ return parseDateTimeOrTimestamp(value);
179
152
  }
180
153
  default:
181
- return value2;
182
- }
183
- };
184
- const PLUGIN_PREFIX = "plugin::";
185
- const API_PREFIX = "api::";
186
- const parsePolicy = (policy2) => {
187
- if (typeof policy2 === "string") {
188
- return { policyName: policy2, config: {} };
154
+ return value;
189
155
  }
190
- const { name, config } = policy2;
191
- return { policyName: name, config };
192
156
  };
193
- const searchLocalPolicy = (policyName, policyContext) => {
194
- const { pluginName, apiName } = policyContext ?? {};
195
- if (pluginName) {
196
- return strapi.policy(`${PLUGIN_PREFIX}${pluginName}.${policyName}`);
197
- }
198
- if (apiName) {
199
- return strapi.policy(`${API_PREFIX}${apiName}.${policyName}`);
157
+ function envFn(key, defaultValue) {
158
+ return ___default.default.has(process.env, key) ? process.env[key] : defaultValue;
159
+ }
160
+ function getKey(key) {
161
+ return process.env[key] ?? "";
162
+ }
163
+ const utils = {
164
+ int(key, defaultValue) {
165
+ if (!___default.default.has(process.env, key)) {
166
+ return defaultValue;
167
+ }
168
+ return parseInt(getKey(key), 10);
169
+ },
170
+ float(key, defaultValue) {
171
+ if (!___default.default.has(process.env, key)) {
172
+ return defaultValue;
173
+ }
174
+ return parseFloat(getKey(key));
175
+ },
176
+ bool(key, defaultValue) {
177
+ if (!___default.default.has(process.env, key)) {
178
+ return defaultValue;
179
+ }
180
+ return getKey(key) === "true";
181
+ },
182
+ json(key, defaultValue) {
183
+ if (!___default.default.has(process.env, key)) {
184
+ return defaultValue;
185
+ }
186
+ try {
187
+ return JSON.parse(getKey(key));
188
+ } catch (error) {
189
+ if (error instanceof Error) {
190
+ throw new Error(`Invalid json environment variable ${key}: ${error.message}`);
191
+ }
192
+ throw error;
193
+ }
194
+ },
195
+ array(key, defaultValue) {
196
+ if (!___default.default.has(process.env, key)) {
197
+ return defaultValue;
198
+ }
199
+ let value = getKey(key);
200
+ if (value.startsWith("[") && value.endsWith("]")) {
201
+ value = value.substring(1, value.length - 1);
202
+ }
203
+ return value.split(",").map((v) => {
204
+ return ___default.default.trim(___default.default.trim(v, " "), '"');
205
+ });
206
+ },
207
+ date(key, defaultValue) {
208
+ if (!___default.default.has(process.env, key)) {
209
+ return defaultValue;
210
+ }
211
+ return new Date(getKey(key));
212
+ },
213
+ /**
214
+ * Gets a value from env that matches oneOf provided values
215
+ * @param {string} key
216
+ * @param {string[]} expectedValues
217
+ * @param {string|undefined} defaultValue
218
+ * @returns {string|undefined}
219
+ */
220
+ oneOf(key, expectedValues, defaultValue) {
221
+ if (!expectedValues) {
222
+ throw new Error(`env.oneOf requires expectedValues`);
223
+ }
224
+ if (defaultValue && !expectedValues.includes(defaultValue)) {
225
+ throw new Error(`env.oneOf requires defaultValue to be included in expectedValues`);
226
+ }
227
+ const rawValue = env(key, defaultValue);
228
+ return expectedValues.includes(rawValue) ? rawValue : defaultValue;
200
229
  }
201
230
  };
202
- const globalPolicy = ({ method, endpoint, controller, action, plugin }) => {
203
- return async (ctx, next) => {
204
- ctx.request.route = {
205
- endpoint: `${method} ${endpoint}`,
206
- controller: ___default.default.toLower(controller),
207
- action: ___default.default.toLower(action),
208
- verb: ___default.default.toLower(method),
209
- plugin
210
- };
211
- await next();
212
- };
213
- };
214
- const resolvePolicies = (config, policyContext) => {
215
- const { pluginName, apiName } = policyContext ?? {};
216
- return config.map((policyConfig) => {
217
- return {
218
- handler: getPolicy(policyConfig, { pluginName, apiName }),
219
- config: typeof policyConfig === "object" && policyConfig.config || {}
220
- };
221
- });
231
+ const env = Object.assign(envFn, utils);
232
+ const SINGLE_TYPE = "singleType";
233
+ const COLLECTION_TYPE = "collectionType";
234
+ const ID_ATTRIBUTE$4 = "id";
235
+ const DOC_ID_ATTRIBUTE$4 = "documentId";
236
+ const PUBLISHED_AT_ATTRIBUTE$1 = "publishedAt";
237
+ const CREATED_BY_ATTRIBUTE$3 = "createdBy";
238
+ const UPDATED_BY_ATTRIBUTE$3 = "updatedBy";
239
+ const CREATED_AT_ATTRIBUTE = "createdAt";
240
+ const UPDATED_AT_ATTRIBUTE = "updatedAt";
241
+ const constants$1 = {
242
+ ID_ATTRIBUTE: ID_ATTRIBUTE$4,
243
+ DOC_ID_ATTRIBUTE: DOC_ID_ATTRIBUTE$4,
244
+ PUBLISHED_AT_ATTRIBUTE: PUBLISHED_AT_ATTRIBUTE$1,
245
+ CREATED_BY_ATTRIBUTE: CREATED_BY_ATTRIBUTE$3,
246
+ UPDATED_BY_ATTRIBUTE: UPDATED_BY_ATTRIBUTE$3,
247
+ CREATED_AT_ATTRIBUTE,
248
+ UPDATED_AT_ATTRIBUTE,
249
+ SINGLE_TYPE,
250
+ COLLECTION_TYPE
222
251
  };
223
- const findPolicy = (name, policyContext) => {
224
- const { pluginName, apiName } = policyContext ?? {};
225
- const resolvedPolicy = strapi.policy(name);
226
- if (resolvedPolicy !== void 0) {
227
- return resolvedPolicy;
252
+ const getTimestamps = (model) => {
253
+ const attributes = [];
254
+ if (fp.has(CREATED_AT_ATTRIBUTE, model.attributes)) {
255
+ attributes.push(CREATED_AT_ATTRIBUTE);
228
256
  }
229
- const localPolicy = searchLocalPolicy(name, { pluginName, apiName });
230
- if (localPolicy !== void 0) {
231
- return localPolicy;
257
+ if (fp.has(UPDATED_AT_ATTRIBUTE, model.attributes)) {
258
+ attributes.push(UPDATED_AT_ATTRIBUTE);
232
259
  }
233
- throw new Error(`Could not find policy "${name}"`);
260
+ return attributes;
234
261
  };
235
- const getPolicy = (policyConfig, policyContext) => {
236
- const { pluginName, apiName } = policyContext ?? {};
237
- if (typeof policyConfig === "function") {
238
- return policyConfig;
262
+ const getCreatorFields = (model) => {
263
+ const attributes = [];
264
+ if (fp.has(CREATED_BY_ATTRIBUTE$3, model.attributes)) {
265
+ attributes.push(CREATED_BY_ATTRIBUTE$3);
239
266
  }
240
- const { policyName, config } = parsePolicy(policyConfig);
241
- const policy2 = findPolicy(policyName, { pluginName, apiName });
242
- if (typeof policy2 === "function") {
243
- return policy2;
267
+ if (fp.has(UPDATED_BY_ATTRIBUTE$3, model.attributes)) {
268
+ attributes.push(UPDATED_BY_ATTRIBUTE$3);
244
269
  }
245
- if (policy2.validator) {
246
- policy2.validator(config);
270
+ return attributes;
271
+ };
272
+ const getNonWritableAttributes = (model) => {
273
+ if (!model)
274
+ return [];
275
+ const nonWritableAttributes = ___default.default.reduce(
276
+ model.attributes,
277
+ (acc, attr, attrName) => attr.writable === false ? acc.concat(attrName) : acc,
278
+ []
279
+ );
280
+ return ___default.default.uniq([
281
+ ID_ATTRIBUTE$4,
282
+ DOC_ID_ATTRIBUTE$4,
283
+ ...getTimestamps(model),
284
+ ...nonWritableAttributes
285
+ ]);
286
+ };
287
+ const getWritableAttributes = (model) => {
288
+ if (!model)
289
+ return [];
290
+ return ___default.default.difference(Object.keys(model.attributes), getNonWritableAttributes(model));
291
+ };
292
+ const isWritableAttribute = (model, attributeName) => {
293
+ return getWritableAttributes(model).includes(attributeName);
294
+ };
295
+ const getNonVisibleAttributes = (model) => {
296
+ const nonVisibleAttributes = ___default.default.reduce(
297
+ model.attributes,
298
+ (acc, attr, attrName) => attr.visible === false ? acc.concat(attrName) : acc,
299
+ []
300
+ );
301
+ return ___default.default.uniq([ID_ATTRIBUTE$4, DOC_ID_ATTRIBUTE$4, ...getTimestamps(model), ...nonVisibleAttributes]);
302
+ };
303
+ const getVisibleAttributes = (model) => {
304
+ return ___default.default.difference(___default.default.keys(model.attributes), getNonVisibleAttributes(model));
305
+ };
306
+ const isVisibleAttribute = (model, attributeName) => {
307
+ return getVisibleAttributes(model).includes(attributeName);
308
+ };
309
+ const getOptions = (model) => ___default.default.assign({ draftAndPublish: false }, ___default.default.get(model, "options", {}));
310
+ const hasDraftAndPublish = (model) => ___default.default.get(model, "options.draftAndPublish", false) === true;
311
+ const isDraft = (data, model) => hasDraftAndPublish(model) && ___default.default.get(data, PUBLISHED_AT_ATTRIBUTE$1) === null;
312
+ const isSingleType = ({ kind = COLLECTION_TYPE }) => kind === SINGLE_TYPE;
313
+ const isCollectionType = ({ kind = COLLECTION_TYPE }) => kind === COLLECTION_TYPE;
314
+ const isKind = (kind) => (model) => model.kind === kind;
315
+ const getStoredPrivateAttributes = (model) => fp.union(
316
+ strapi?.config?.get("api.responses.privateAttributes", []) ?? [],
317
+ fp.getOr([], "options.privateAttributes", model)
318
+ );
319
+ const getPrivateAttributes = (model) => {
320
+ return ___default.default.union(
321
+ getStoredPrivateAttributes(model),
322
+ ___default.default.keys(___default.default.pickBy(model.attributes, (attr) => !!attr.private))
323
+ );
324
+ };
325
+ const isPrivateAttribute = (model, attributeName) => {
326
+ if (model?.attributes?.[attributeName]?.private === true) {
327
+ return true;
247
328
  }
248
- return policy2.handler;
329
+ return getStoredPrivateAttributes(model).includes(attributeName);
249
330
  };
250
- const createPolicy = (options) => {
251
- const { name = "unnamed", validator, handler } = options;
252
- const wrappedValidator = (config) => {
253
- if (validator) {
254
- try {
255
- validator(config);
256
- } catch (e) {
257
- throw new Error(`Invalid config passed to "${name}" policy.`);
258
- }
259
- }
260
- };
261
- return {
262
- name,
263
- validator: wrappedValidator,
264
- handler
265
- };
331
+ const isScalarAttribute = (attribute) => {
332
+ return !["media", "component", "relation", "dynamiczone"].includes(attribute?.type);
266
333
  };
267
- const createPolicyContext = (type, ctx) => {
268
- return Object.assign(
269
- {
270
- is: fp.eq(type),
271
- get type() {
272
- return type;
273
- }
334
+ const isMediaAttribute = (attribute) => attribute?.type === "media";
335
+ const isRelationalAttribute = (attribute) => attribute?.type === "relation";
336
+ const isComponentAttribute = (attribute) => ["component", "dynamiczone"].includes(attribute?.type);
337
+ const isDynamicZoneAttribute = (attribute) => attribute?.type === "dynamiczone";
338
+ const isMorphToRelationalAttribute = (attribute) => {
339
+ return isRelationalAttribute(attribute) && attribute?.relation?.startsWith?.("morphTo");
340
+ };
341
+ const getComponentAttributes = (schema) => {
342
+ return ___default.default.reduce(
343
+ schema.attributes,
344
+ (acc, attr, attrName) => {
345
+ if (isComponentAttribute(attr))
346
+ acc.push(attrName);
347
+ return acc;
274
348
  },
275
- ctx
349
+ []
276
350
  );
277
351
  };
278
- const policy = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
279
- __proto__: null,
280
- createPolicy,
281
- createPolicyContext,
282
- get: getPolicy,
283
- globalPolicy,
284
- resolve: resolvePolicies
285
- }, Symbol.toStringTag, { value: "Module" }));
286
- const regex = /\$\{[^()]*\}/g;
287
- const excludeConfigPaths = ["info.scripts"];
288
- const isObj$3 = (value2) => _$1.isPlainObject(value2);
289
- const templateConfiguration = (obj, configPath = "") => {
290
- return Object.keys(obj).reduce((acc, key) => {
291
- const value = obj[key];
292
- if (isObj$3(value) && !_$1.isString(value)) {
293
- acc[key] = templateConfiguration(value, `${configPath}.${key}`);
294
- } else if (_$1.isString(value) && !excludeConfigPaths.includes(configPath.substr(1)) && value.match(regex) !== null) {
295
- acc[key] = eval("`" + value + "`");
296
- } else {
297
- acc[key] = value;
298
- }
299
- return acc;
300
- }, {});
301
- };
302
- const formatYupInnerError = (yupError) => ({
303
- path: fp.toPath(yupError.path),
304
- message: yupError.message,
305
- name: yupError.name
306
- });
307
- const formatYupErrors = (yupError) => ({
308
- errors: fp.isEmpty(yupError.inner) ? [formatYupInnerError(yupError)] : yupError.inner.map(formatYupInnerError),
309
- message: yupError.message
310
- });
311
- class ApplicationError extends Error {
312
- name;
313
- details;
314
- message;
315
- constructor(message = "An application error occured", details = {}) {
316
- super();
317
- this.name = "ApplicationError";
318
- this.message = message;
319
- this.details = details;
320
- }
321
- }
322
- class ValidationError extends ApplicationError {
323
- constructor(message, details) {
324
- super(message, details);
325
- this.name = "ValidationError";
326
- }
327
- }
328
- class YupValidationError extends ValidationError {
329
- constructor(yupError, message) {
330
- super("Validation");
331
- const { errors: errors2, message: yupMessage } = formatYupErrors(yupError);
332
- this.message = message || yupMessage;
333
- this.details = { errors: errors2 };
334
- }
335
- }
336
- class PaginationError extends ApplicationError {
337
- constructor(message = "Invalid pagination", details) {
338
- super(message, details);
339
- this.name = "PaginationError";
340
- this.message = message;
341
- }
342
- }
343
- class NotFoundError extends ApplicationError {
344
- constructor(message = "Entity not found", details) {
345
- super(message, details);
346
- this.name = "NotFoundError";
347
- this.message = message;
348
- }
349
- }
350
- class ForbiddenError extends ApplicationError {
351
- constructor(message = "Forbidden access", details) {
352
- super(message, details);
353
- this.name = "ForbiddenError";
354
- this.message = message;
355
- }
356
- }
357
- class UnauthorizedError extends ApplicationError {
358
- constructor(message = "Unauthorized", details) {
359
- super(message, details);
360
- this.name = "UnauthorizedError";
361
- this.message = message;
362
- }
363
- }
364
- class RateLimitError extends ApplicationError {
365
- constructor(message = "Too many requests, please try again later.", details) {
366
- super(message, details);
367
- this.name = "RateLimitError";
368
- this.message = message;
369
- this.details = details || {};
370
- }
371
- }
372
- class PayloadTooLargeError extends ApplicationError {
373
- constructor(message = "Entity too large", details) {
374
- super(message, details);
375
- this.name = "PayloadTooLargeError";
376
- this.message = message;
377
- }
378
- }
379
- class PolicyError extends ForbiddenError {
380
- constructor(message = "Policy Failed", details) {
381
- super(message, details);
382
- this.name = "PolicyError";
383
- this.message = message;
384
- this.details = details || {};
385
- }
386
- }
387
- class NotImplementedError extends ApplicationError {
388
- constructor(message = "This feature is not implemented yet", details) {
389
- super(message, details);
390
- this.name = "NotImplementedError";
391
- this.message = message;
392
- }
393
- }
394
- const errors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
395
- __proto__: null,
396
- ApplicationError,
397
- ForbiddenError,
398
- HttpError: httpErrors.HttpError,
399
- NotFoundError,
400
- NotImplementedError,
401
- PaginationError,
402
- PayloadTooLargeError,
403
- PolicyError,
404
- RateLimitError,
405
- UnauthorizedError,
406
- ValidationError,
407
- YupValidationError
408
- }, Symbol.toStringTag, { value: "Module" }));
409
- const handleYupError = (error, errorMessage) => {
410
- throw new YupValidationError(error, errorMessage);
411
- };
412
- const defaultValidationParam = { strict: true, abortEarly: false };
413
- const validateYupSchema = (schema, options = {}) => async (body, errorMessage) => {
414
- try {
415
- const optionsWithDefaults = fp.defaults(defaultValidationParam, options);
416
- const result = await schema.validate(body, optionsWithDefaults);
417
- return result;
418
- } catch (e) {
419
- if (e instanceof yup__namespace.ValidationError) {
420
- handleYupError(e, errorMessage);
421
- }
422
- throw e;
423
- }
424
- };
425
- const validateYupSchemaSync = (schema, options = {}) => (body, errorMessage) => {
426
- try {
427
- const optionsWithDefaults = fp.defaults(defaultValidationParam, options);
428
- return schema.validateSync(body, optionsWithDefaults);
429
- } catch (e) {
430
- if (e instanceof yup__namespace.ValidationError) {
431
- handleYupError(e, errorMessage);
432
- }
433
- throw e;
434
- }
435
- };
436
- const nameToSlug = (name, options = { separator: "-" }) => slugify__default.default(name, options);
437
- const nameToCollectionName = (name) => slugify__default.default(name, { separator: "_" });
438
- const toRegressedEnumValue = (value2) => slugify__default.default(value2, {
439
- decamelize: false,
440
- lowercase: false,
441
- separator: "_"
442
- });
443
- const getCommonBeginning = (...strings) => ___default.default.takeWhile(strings[0], (char, index2) => strings.every((string) => string[index2] === char)).join(
444
- ""
445
- );
446
- const getCommonPath = (...paths) => {
447
- const [segments, ...otherSegments] = paths.map((it) => ___default.default.split(it, "/"));
448
- return ___default.default.join(
449
- ___default.default.takeWhile(segments, (str, index2) => otherSegments.every((it) => it[index2] === str)),
450
- "/"
451
- );
452
- };
453
- const escapeQuery = (query, charsToEscape, escapeChar = "\\") => {
454
- return query.split("").reduce(
455
- (escapedQuery, char) => charsToEscape.includes(char) ? `${escapedQuery}${escapeChar}${char}` : `${escapedQuery}${char}`,
456
- ""
457
- );
458
- };
459
- const stringIncludes = (arr, val) => arr.map(String).includes(String(val));
460
- const stringEquals = (a, b) => String(a) === String(b);
461
- const isCamelCase = (value2) => /^[a-z][a-zA-Z0-9]+$/.test(value2);
462
- const isKebabCase = (value2) => /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/.test(value2);
463
- const startsWithANumber = (value2) => /^[0-9]/.test(value2);
464
- const joinBy = (joint, ...args) => {
465
- const trim = fp.trimChars(joint);
466
- const trimEnd = fp.trimCharsEnd(joint);
467
- const trimStart = fp.trimCharsStart(joint);
468
- return args.reduce((url, path, index2) => {
469
- if (args.length === 1)
470
- return path;
471
- if (index2 === 0)
472
- return trimEnd(path);
473
- if (index2 === args.length - 1)
474
- return url + joint + trimStart(path);
475
- return url + joint + trim(path);
476
- }, "");
477
- };
478
- const toKebabCase = (value2) => _$1.kebabCase(value2);
479
- const { toString } = Object.prototype;
480
- const errorToString = Error.prototype.toString;
481
- const regExpToString = RegExp.prototype.toString;
482
- const symbolToString = typeof Symbol !== "undefined" ? Symbol.prototype.toString : () => "";
483
- const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/;
484
- function printNumber(val) {
485
- if (val != +val)
486
- return "NaN";
487
- const isNegativeZero = val === 0 && 1 / val < 0;
488
- return isNegativeZero ? "-0" : `${val}`;
489
- }
490
- function printSimpleValue(val, quoteStrings = false) {
491
- if (val == null || val === true || val === false)
492
- return `${val}`;
493
- if (typeof val === "number")
494
- return printNumber(val);
495
- if (typeof val === "string")
496
- return quoteStrings ? `"${val}"` : val;
497
- if (typeof val === "function")
498
- return `[Function ${val.name || "anonymous"}]`;
499
- if (typeof val === "symbol")
500
- return symbolToString.call(val).replace(SYMBOL_REGEXP, "Symbol($1)");
501
- const tag = toString.call(val).slice(8, -1);
502
- if (tag === "Date") {
503
- const v = val;
504
- return Number.isNaN(v.getTime()) ? `${v}` : v.toISOString();
505
- }
506
- if (tag === "Error" || val instanceof Error)
507
- return `[${errorToString.call(val)}]`;
508
- if (tag === "RegExp")
509
- return regExpToString.call(val);
510
- return null;
511
- }
512
- function printValue(value2, quoteStrings) {
513
- const result = printSimpleValue(value2, quoteStrings);
514
- if (result !== null)
515
- return result;
516
- return JSON.stringify(
517
- value2,
518
- function replacer(key2, value22) {
519
- const result2 = printSimpleValue(this[key2], quoteStrings);
520
- if (result2 !== null)
521
- return result2;
522
- return value22;
523
- },
524
- 2
525
- );
526
- }
527
- const strapiID = () => new StrapiIDSchema();
528
- const isNotNilTest = (value2) => !___default.default.isNil(value2);
529
- const isNotNullTest = (value2) => !___default.default.isNull(value2);
530
- yup__namespace.addMethod(yup__namespace.mixed, "notNil", function isNotNill(msg = "${path} must be defined.") {
531
- return this.test("defined", msg, isNotNilTest);
532
- });
533
- yup__namespace.addMethod(yup__namespace.mixed, "notNull", function isNotNull(msg = "${path} cannot be null.") {
534
- return this.test("defined", msg, isNotNullTest);
535
- });
536
- yup__namespace.addMethod(yup__namespace.mixed, "isFunction", function isFunction(message = "${path} is not a function") {
537
- return this.test(
538
- "is a function",
539
- message,
540
- (value2) => ___default.default.isUndefined(value2) || ___default.default.isFunction(value2)
541
- );
542
- });
543
- yup__namespace.addMethod(
544
- yup__namespace.string,
545
- "isCamelCase",
546
- function isCamelCase$1(message = "${path} is not in camel case (anExampleOfCamelCase)") {
547
- return this.test(
548
- "is in camelCase",
549
- message,
550
- (value2) => value2 ? isCamelCase(value2) : true
551
- );
552
- }
553
- );
554
- yup__namespace.addMethod(
555
- yup__namespace.string,
556
- "isKebabCase",
557
- function isKebabCase$1(message = "${path} is not in kebab case (an-example-of-kebab-case)") {
558
- return this.test(
559
- "is in kebab-case",
560
- message,
561
- (value2) => value2 ? isKebabCase(value2) : true
562
- );
563
- }
564
- );
565
- yup__namespace.addMethod(
566
- yup__namespace.object,
567
- "onlyContainsFunctions",
568
- function onlyContainsFunctions(message = "${path} contains values that are not functions") {
569
- return this.test(
570
- "only contains functions",
571
- message,
572
- (value2) => ___default.default.isUndefined(value2) || value2 && Object.values(value2).every(___default.default.isFunction)
573
- );
574
- }
575
- );
576
- yup__namespace.addMethod(
577
- yup__namespace.array,
578
- "uniqueProperty",
579
- function uniqueProperty(propertyName, message) {
580
- return this.test("unique", message, function unique(list) {
581
- const errors2 = [];
582
- list?.forEach((element, index2) => {
583
- const sameElements = list.filter(
584
- (e) => fp.get(propertyName, e) === fp.get(propertyName, element)
585
- );
586
- if (sameElements.length > 1) {
587
- errors2.push(
588
- this.createError({
589
- path: `${this.path}[${index2}].${propertyName}`,
590
- message
591
- })
592
- );
593
- }
594
- });
595
- if (errors2.length) {
596
- throw new yup__namespace.ValidationError(errors2);
597
- }
598
- return true;
599
- });
600
- }
601
- );
602
- class StrapiIDSchema extends yup__namespace.MixedSchema {
603
- constructor() {
604
- super({ type: "strapiID" });
605
- }
606
- _typeCheck(value2) {
607
- return typeof value2 === "string" || fp.isNumber(value2) && fp.isInteger(value2) && value2 >= 0;
608
- }
609
- }
610
- yup__namespace.setLocale({
611
- mixed: {
612
- notType(options) {
613
- const { path, type, value: value2, originalValue } = options;
614
- const isCast = originalValue != null && originalValue !== value2;
615
- const msg = `${path} must be a \`${type}\` type, but the final value was: \`${printValue(value2, true)}\`${isCast ? ` (cast from the value \`${printValue(originalValue, true)}\`).` : "."}`;
616
- return msg;
617
- }
618
- }
619
- });
620
- const yup = /* @__PURE__ */ _mergeNamespaces({
621
- __proto__: null,
622
- StrapiIDSchema,
623
- strapiID
624
- }, [yup__namespace]);
625
- const removeUndefined = (obj2) => ___default.default.pickBy(obj2, (value2) => typeof value2 !== "undefined");
626
- const keysDeep = (obj2, path = []) => !___default.default.isObject(obj2) ? [path.join(".")] : ___default.default.reduce(
627
- obj2,
628
- (acc2, next, key2) => ___default.default.concat(acc2, keysDeep(next, [...path, key2])),
629
- []
630
- );
631
- const getConfigUrls = (config, forAdminBuild = false) => {
632
- const serverConfig = config.get("server");
633
- const adminConfig = config.get("admin");
634
- let serverUrl = ___default.default.get(serverConfig, "url", "");
635
- serverUrl = ___default.default.trim(serverUrl, "/ ");
636
- if (typeof serverUrl !== "string") {
637
- throw new Error("Invalid server url config. Make sure the url is a string.");
638
- }
639
- if (serverUrl.startsWith("http")) {
640
- try {
641
- serverUrl = ___default.default.trim(new URL(serverConfig.url).toString(), "/");
642
- } catch (e) {
643
- throw new Error(
644
- "Invalid server url config. Make sure the url defined in server.js is valid."
645
- );
646
- }
647
- } else if (serverUrl !== "") {
648
- serverUrl = `/${serverUrl}`;
649
- }
650
- let adminUrl = ___default.default.get(adminConfig, "url", "/admin");
651
- adminUrl = ___default.default.trim(adminUrl, "/ ");
652
- if (typeof adminUrl !== "string") {
653
- throw new Error("Invalid admin url config. Make sure the url is a non-empty string.");
654
- }
655
- if (adminUrl.startsWith("http")) {
656
- try {
657
- adminUrl = ___default.default.trim(new URL(adminUrl).toString(), "/");
658
- } catch (e) {
659
- throw new Error("Invalid admin url config. Make sure the url defined in server.js is valid.");
660
- }
661
- } else {
662
- adminUrl = `${serverUrl}/${adminUrl}`;
663
- }
664
- let adminPath = adminUrl;
665
- if (serverUrl.startsWith("http") && adminUrl.startsWith("http") && new URL(adminUrl).origin === new URL(serverUrl).origin && !forAdminBuild) {
666
- adminPath = adminUrl.replace(getCommonPath(serverUrl, adminUrl), "");
667
- adminPath = `/${___default.default.trim(adminPath, "/")}`;
668
- } else if (adminUrl.startsWith("http")) {
669
- adminPath = new URL(adminUrl).pathname;
670
- }
671
- return {
672
- serverUrl,
673
- adminUrl,
674
- adminPath
675
- };
676
- };
677
- const getAbsoluteUrl = (adminOrServer) => (config, forAdminBuild = false) => {
678
- const { serverUrl, adminUrl } = getConfigUrls(config, forAdminBuild);
679
- const url = adminOrServer === "server" ? serverUrl : adminUrl;
680
- if (url.startsWith("http")) {
681
- return url;
682
- }
683
- const hostname = config.get("environment") === "development" && ["127.0.0.1", "0.0.0.0"].includes(config.get("server.host")) ? "localhost" : config.get("server.host");
684
- return `http://${hostname}:${config.get("server.port")}${url}`;
685
- };
686
- const getAbsoluteAdminUrl = getAbsoluteUrl("admin");
687
- const getAbsoluteServerUrl = getAbsoluteUrl("server");
688
- const generateTimestampCode = (date) => {
689
- const referDate = date || /* @__PURE__ */ new Date();
690
- return referDate.getTime().toString(36);
691
- };
692
- const SINGLE_TYPE = "singleType";
693
- const COLLECTION_TYPE = "collectionType";
694
- const ID_ATTRIBUTE = "id";
695
- const PUBLISHED_AT_ATTRIBUTE$1 = "publishedAt";
696
- const CREATED_BY_ATTRIBUTE$3 = "createdBy";
697
- const UPDATED_BY_ATTRIBUTE$3 = "updatedBy";
698
- const CREATED_AT_ATTRIBUTE = "createdAt";
699
- const UPDATED_AT_ATTRIBUTE = "updatedAt";
700
- const DP_PUB_STATE_LIVE = "live";
701
- const DP_PUB_STATE_PREVIEW = "preview";
702
- const DP_PUB_STATES = [DP_PUB_STATE_LIVE, DP_PUB_STATE_PREVIEW];
703
- const constants$1 = {
704
- ID_ATTRIBUTE,
705
- PUBLISHED_AT_ATTRIBUTE: PUBLISHED_AT_ATTRIBUTE$1,
706
- CREATED_BY_ATTRIBUTE: CREATED_BY_ATTRIBUTE$3,
707
- UPDATED_BY_ATTRIBUTE: UPDATED_BY_ATTRIBUTE$3,
708
- CREATED_AT_ATTRIBUTE,
709
- UPDATED_AT_ATTRIBUTE,
710
- DP_PUB_STATES,
711
- DP_PUB_STATE_LIVE,
712
- DP_PUB_STATE_PREVIEW,
713
- SINGLE_TYPE,
714
- COLLECTION_TYPE
715
- };
716
- const getTimestamps = (model) => {
717
- const attributes = [];
718
- if (fp.has(CREATED_AT_ATTRIBUTE, model.attributes)) {
719
- attributes.push(CREATED_AT_ATTRIBUTE);
720
- }
721
- if (fp.has(UPDATED_AT_ATTRIBUTE, model.attributes)) {
722
- attributes.push(UPDATED_AT_ATTRIBUTE);
723
- }
724
- return attributes;
725
- };
726
- const getCreatorFields = (model) => {
727
- const attributes = [];
728
- if (fp.has(CREATED_BY_ATTRIBUTE$3, model.attributes)) {
729
- attributes.push(CREATED_BY_ATTRIBUTE$3);
730
- }
731
- if (fp.has(UPDATED_BY_ATTRIBUTE$3, model.attributes)) {
732
- attributes.push(UPDATED_BY_ATTRIBUTE$3);
733
- }
734
- return attributes;
735
- };
736
- const getNonWritableAttributes = (model) => {
737
- if (!model)
738
- return [];
739
- const nonWritableAttributes = ___default.default.reduce(
740
- model.attributes,
741
- (acc2, attr, attrName) => attr.writable === false ? acc2.concat(attrName) : acc2,
742
- []
743
- );
744
- return ___default.default.uniq([ID_ATTRIBUTE, ...getTimestamps(model), ...nonWritableAttributes]);
745
- };
746
- const getWritableAttributes = (model) => {
747
- if (!model)
748
- return [];
749
- return ___default.default.difference(Object.keys(model.attributes), getNonWritableAttributes(model));
750
- };
751
- const isWritableAttribute = (model, attributeName) => {
752
- return getWritableAttributes(model).includes(attributeName);
753
- };
754
- const getNonVisibleAttributes = (model) => {
755
- const nonVisibleAttributes = ___default.default.reduce(
756
- model.attributes,
757
- (acc2, attr, attrName) => attr.visible === false ? acc2.concat(attrName) : acc2,
758
- []
759
- );
760
- return ___default.default.uniq([ID_ATTRIBUTE, ...getTimestamps(model), ...nonVisibleAttributes]);
761
- };
762
- const getVisibleAttributes = (model) => {
763
- return ___default.default.difference(___default.default.keys(model.attributes), getNonVisibleAttributes(model));
764
- };
765
- const isVisibleAttribute = (model, attributeName) => {
766
- return getVisibleAttributes(model).includes(attributeName);
767
- };
768
- const getOptions = (model) => ___default.default.assign({ draftAndPublish: false }, ___default.default.get(model, "options", {}));
769
- const hasDraftAndPublish = (model) => ___default.default.get(model, "options.draftAndPublish", false) === true;
770
- const isDraft = (data, model) => hasDraftAndPublish(model) && ___default.default.get(data, PUBLISHED_AT_ATTRIBUTE$1) === null;
771
- const isSingleType = ({ kind = COLLECTION_TYPE }) => kind === SINGLE_TYPE;
772
- const isCollectionType = ({ kind = COLLECTION_TYPE }) => kind === COLLECTION_TYPE;
773
- const isKind = (kind) => (model) => model.kind === kind;
774
- const getStoredPrivateAttributes = (model) => fp.union(
775
- strapi?.config?.get("api.responses.privateAttributes", []) ?? [],
776
- fp.getOr([], "options.privateAttributes", model)
777
- );
778
- const getPrivateAttributes = (model) => {
779
- return ___default.default.union(
780
- getStoredPrivateAttributes(model),
781
- ___default.default.keys(___default.default.pickBy(model.attributes, (attr) => !!attr.private))
782
- );
783
- };
784
- const isPrivateAttribute = (model, attributeName) => {
785
- if (model?.attributes?.[attributeName]?.private === true) {
786
- return true;
787
- }
788
- return getStoredPrivateAttributes(model).includes(attributeName);
789
- };
790
- const isScalarAttribute = (attribute) => {
791
- return !["media", "component", "relation", "dynamiczone"].includes(attribute?.type);
792
- };
793
- const isMediaAttribute = (attribute) => attribute?.type === "media";
794
- const isRelationalAttribute = (attribute) => attribute?.type === "relation";
795
- const isComponentAttribute = (attribute) => ["component", "dynamiczone"].includes(attribute?.type);
796
- const isDynamicZoneAttribute = (attribute) => attribute?.type === "dynamiczone";
797
- const isMorphToRelationalAttribute = (attribute) => {
798
- return isRelationalAttribute(attribute) && attribute?.relation?.startsWith?.("morphTo");
799
- };
800
- const getComponentAttributes = (schema) => {
801
- return ___default.default.reduce(
802
- schema.attributes,
803
- (acc2, attr, attrName) => {
804
- if (isComponentAttribute(attr))
805
- acc2.push(attrName);
806
- return acc2;
807
- },
808
- []
809
- );
810
- };
811
- const getScalarAttributes = (schema) => {
812
- return ___default.default.reduce(
813
- schema.attributes,
814
- (acc2, attr, attrName) => {
815
- if (isScalarAttribute(attr))
816
- acc2.push(attrName);
817
- return acc2;
818
- },
819
- []
820
- );
352
+ const getScalarAttributes = (schema) => {
353
+ return ___default.default.reduce(
354
+ schema.attributes,
355
+ (acc, attr, attrName) => {
356
+ if (isScalarAttribute(attr))
357
+ acc.push(attrName);
358
+ return acc;
359
+ },
360
+ []
361
+ );
821
362
  };
822
363
  const isTypedAttribute = (attribute, type) => {
823
364
  return ___default.default.has(attribute, "type") && attribute.type === type;
@@ -855,103 +396,6 @@ const contentTypes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.define
855
396
  isVisibleAttribute,
856
397
  isWritableAttribute
857
398
  }, Symbol.toStringTag, { value: "Module" }));
858
- function envFn(key2, defaultValue) {
859
- return ___default.default.has(process.env, key2) ? process.env[key2] : defaultValue;
860
- }
861
- function getKey(key2) {
862
- return process.env[key2] ?? "";
863
- }
864
- const utils = {
865
- int(key2, defaultValue) {
866
- if (!___default.default.has(process.env, key2)) {
867
- return defaultValue;
868
- }
869
- return parseInt(getKey(key2), 10);
870
- },
871
- float(key2, defaultValue) {
872
- if (!___default.default.has(process.env, key2)) {
873
- return defaultValue;
874
- }
875
- return parseFloat(getKey(key2));
876
- },
877
- bool(key2, defaultValue) {
878
- if (!___default.default.has(process.env, key2)) {
879
- return defaultValue;
880
- }
881
- return getKey(key2) === "true";
882
- },
883
- json(key2, defaultValue) {
884
- if (!___default.default.has(process.env, key2)) {
885
- return defaultValue;
886
- }
887
- try {
888
- return JSON.parse(getKey(key2));
889
- } catch (error) {
890
- if (error instanceof Error) {
891
- throw new Error(`Invalid json environment variable ${key2}: ${error.message}`);
892
- }
893
- throw error;
894
- }
895
- },
896
- array(key2, defaultValue) {
897
- if (!___default.default.has(process.env, key2)) {
898
- return defaultValue;
899
- }
900
- let value2 = getKey(key2);
901
- if (value2.startsWith("[") && value2.endsWith("]")) {
902
- value2 = value2.substring(1, value2.length - 1);
903
- }
904
- return value2.split(",").map((v) => {
905
- return ___default.default.trim(___default.default.trim(v, " "), '"');
906
- });
907
- },
908
- date(key2, defaultValue) {
909
- if (!___default.default.has(process.env, key2)) {
910
- return defaultValue;
911
- }
912
- return new Date(getKey(key2));
913
- },
914
- /**
915
- * Gets a value from env that matches oneOf provided values
916
- * @param {string} key
917
- * @param {string[]} expectedValues
918
- * @param {string|undefined} defaultValue
919
- * @returns {string|undefined}
920
- */
921
- oneOf(key2, expectedValues, defaultValue) {
922
- if (!expectedValues) {
923
- throw new Error(`env.oneOf requires expectedValues`);
924
- }
925
- if (defaultValue && !expectedValues.includes(defaultValue)) {
926
- throw new Error(`env.oneOf requires defaultValue to be included in expectedValues`);
927
- }
928
- const rawValue = env(key2, defaultValue);
929
- return expectedValues.includes(rawValue) ? rawValue : defaultValue;
930
- }
931
- };
932
- const env = Object.assign(envFn, utils);
933
- const MANY_RELATIONS = ["oneToMany", "manyToMany"];
934
- const getRelationalFields = (contentType) => {
935
- return Object.keys(contentType.attributes).filter((attributeName) => {
936
- return contentType.attributes[attributeName].type === "relation";
937
- });
938
- };
939
- const isOneToAny = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "oneToMany"].includes(attribute.relation);
940
- const isManyToAny = (attribute) => isRelationalAttribute(attribute) && ["manyToMany", "manyToOne"].includes(attribute.relation);
941
- const isAnyToOne = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "manyToOne"].includes(attribute.relation);
942
- const isAnyToMany = (attribute) => isRelationalAttribute(attribute) && ["oneToMany", "manyToMany"].includes(attribute.relation);
943
- const constants = {
944
- MANY_RELATIONS
945
- };
946
- const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
947
- __proto__: null,
948
- constants,
949
- getRelationalFields,
950
- isAnyToMany,
951
- isAnyToOne,
952
- isManyToAny,
953
- isOneToAny
954
- }, Symbol.toStringTag, { value: "Module" }));
955
399
  const { CREATED_BY_ATTRIBUTE: CREATED_BY_ATTRIBUTE$2, UPDATED_BY_ATTRIBUTE: UPDATED_BY_ATTRIBUTE$2 } = constants$1;
956
400
  const setCreatorFields = ({ user, isEdition = false }) => (data) => {
957
401
  if (isEdition) {
@@ -1047,26 +491,26 @@ const providerFactory = (options = {}) => {
1047
491
  };
1048
492
  return {
1049
493
  hooks: state.hooks,
1050
- async register(key2, item) {
1051
- if (throwOnDuplicates && this.has(key2)) {
1052
- throw new Error(`Duplicated item key: ${key2}`);
494
+ async register(key, item) {
495
+ if (throwOnDuplicates && this.has(key)) {
496
+ throw new Error(`Duplicated item key: ${key}`);
1053
497
  }
1054
- await state.hooks.willRegister.call({ key: key2, value: item });
1055
- state.registry.set(key2, item);
1056
- await state.hooks.didRegister.call({ key: key2, value: fp.cloneDeep(item) });
498
+ await state.hooks.willRegister.call({ key, value: item });
499
+ state.registry.set(key, item);
500
+ await state.hooks.didRegister.call({ key, value: fp.cloneDeep(item) });
1057
501
  return this;
1058
502
  },
1059
- async delete(key2) {
1060
- if (this.has(key2)) {
1061
- const item = this.get(key2);
1062
- await state.hooks.willDelete.call({ key: key2, value: fp.cloneDeep(item) });
1063
- state.registry.delete(key2);
1064
- await state.hooks.didDelete.call({ key: key2, value: fp.cloneDeep(item) });
503
+ async delete(key) {
504
+ if (this.has(key)) {
505
+ const item = this.get(key);
506
+ await state.hooks.willDelete.call({ key, value: fp.cloneDeep(item) });
507
+ state.registry.delete(key);
508
+ await state.hooks.didDelete.call({ key, value: fp.cloneDeep(item) });
1065
509
  }
1066
510
  return this;
1067
511
  },
1068
- get(key2) {
1069
- return state.registry.get(key2);
512
+ get(key) {
513
+ return state.registry.get(key);
1070
514
  },
1071
515
  getWhere(filters2 = {}) {
1072
516
  const items = this.values();
@@ -1075,7 +519,7 @@ const providerFactory = (options = {}) => {
1075
519
  return items;
1076
520
  }
1077
521
  return items.filter((item) => {
1078
- return filtersEntries.every(([key2, value2]) => item[key2] === value2);
522
+ return filtersEntries.every(([key, value]) => item[key] === value);
1079
523
  });
1080
524
  },
1081
525
  values() {
@@ -1084,93 +528,22 @@ const providerFactory = (options = {}) => {
1084
528
  keys() {
1085
529
  return Array.from(state.registry.keys());
1086
530
  },
1087
- has(key2) {
1088
- return state.registry.has(key2);
531
+ has(key) {
532
+ return state.registry.has(key);
1089
533
  },
1090
534
  size() {
1091
535
  return state.registry.size;
1092
536
  },
1093
537
  async clear() {
1094
538
  const keys = this.keys();
1095
- for (const key2 of keys) {
1096
- await this.delete(key2);
539
+ for (const key of keys) {
540
+ await this.delete(key);
1097
541
  }
1098
542
  return this;
1099
543
  }
1100
544
  };
1101
545
  };
1102
- const STRAPI_DEFAULTS = {
1103
- offset: {
1104
- start: 0,
1105
- limit: 10
1106
- },
1107
- page: {
1108
- page: 1,
1109
- pageSize: 10
1110
- }
1111
- };
1112
- const paginationAttributes = ["start", "limit", "page", "pageSize"];
1113
- const withMaxLimit = (limit, maxLimit = -1) => {
1114
- if (maxLimit === -1 || limit < maxLimit) {
1115
- return limit;
1116
- }
1117
- return maxLimit;
1118
- };
1119
- const ensureMinValues = ({ start, limit }) => ({
1120
- start: Math.max(start, 0),
1121
- limit: limit === -1 ? limit : Math.max(limit, 1)
1122
- });
1123
- const ensureMaxValues = (maxLimit = -1) => ({ start, limit }) => ({
1124
- start,
1125
- limit: withMaxLimit(limit, maxLimit)
1126
- });
1127
- const withNoLimit = (pagination2, maxLimit = -1) => ({
1128
- ...pagination2,
1129
- limit: pagination2.limit === -1 ? maxLimit : pagination2.limit
1130
- });
1131
- const withDefaultPagination = (args, { defaults = {}, maxLimit = -1 } = {}) => {
1132
- const defaultValues = fp.merge(STRAPI_DEFAULTS, defaults);
1133
- const usePagePagination = !fp.isNil(args.page) || !fp.isNil(args.pageSize);
1134
- const useOffsetPagination = !fp.isNil(args.start) || !fp.isNil(args.limit);
1135
- const ensureValidValues = fp.pipe(ensureMinValues, ensureMaxValues(maxLimit));
1136
- if (!usePagePagination && !useOffsetPagination) {
1137
- return fp.merge(args, ensureValidValues(defaultValues.offset));
1138
- }
1139
- if (usePagePagination && useOffsetPagination) {
1140
- throw new PaginationError("Cannot use both page & offset pagination in the same query");
1141
- }
1142
- const pagination2 = {
1143
- start: 0,
1144
- limit: 0
1145
- };
1146
- if (useOffsetPagination) {
1147
- const { start, limit } = fp.merge(defaultValues.offset, args);
1148
- Object.assign(pagination2, { start, limit });
1149
- }
1150
- if (usePagePagination) {
1151
- const { page, pageSize } = fp.merge(defaultValues.page, {
1152
- ...args,
1153
- pageSize: Math.max(1, args.pageSize ?? 0)
1154
- });
1155
- Object.assign(pagination2, {
1156
- start: (page - 1) * pageSize,
1157
- limit: pageSize
1158
- });
1159
- }
1160
- Object.assign(pagination2, withNoLimit(pagination2, maxLimit));
1161
- const replacePaginationAttributes = fp.pipe(
1162
- // Remove pagination attributes
1163
- fp.omit(paginationAttributes),
1164
- // Merge the object with the new pagination + ensure minimum & maximum values
1165
- fp.merge(ensureValidValues(pagination2))
1166
- );
1167
- return replacePaginationAttributes(args);
1168
- };
1169
- const pagination = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1170
- __proto__: null,
1171
- withDefaultPagination
1172
- }, Symbol.toStringTag, { value: "Module" }));
1173
- function pipeAsync(...fns) {
546
+ function pipe(...fns) {
1174
547
  const [firstFn, ...fnRest] = fns;
1175
548
  return async (...args) => {
1176
549
  let res = await firstFn.apply(firstFn, args);
@@ -1180,34 +553,37 @@ function pipeAsync(...fns) {
1180
553
  return res;
1181
554
  };
1182
555
  }
1183
- const mapAsync = fp.curry(pMap__default.default);
1184
- const reduceAsync = (mixedArray) => async (iteratee, initialValue) => {
1185
- let acc2 = initialValue;
556
+ const map = fp.curry(pMap__default.default);
557
+ const reduce = (mixedArray) => async (iteratee, initialValue) => {
558
+ let acc = initialValue;
1186
559
  for (let i = 0; i < mixedArray.length; i += 1) {
1187
- acc2 = await iteratee(acc2, await mixedArray[i], i);
560
+ acc = await iteratee(acc, await mixedArray[i], i);
1188
561
  }
1189
- return acc2;
562
+ return acc;
1190
563
  };
1191
- const forEachAsync = async (array, func, options) => {
1192
- await pMap__default.default(array, func, options);
1193
- };
1194
- const visitor$7 = ({ key: key2, attribute }, { remove }) => {
564
+ const async = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
565
+ __proto__: null,
566
+ map,
567
+ pipe,
568
+ reduce
569
+ }, Symbol.toStringTag, { value: "Module" }));
570
+ const visitor$8 = ({ key, attribute }, { remove }) => {
1195
571
  if (attribute?.type === "password") {
1196
- remove(key2);
572
+ remove(key);
1197
573
  }
1198
574
  };
1199
- const visitor$6 = ({ schema, key: key2, attribute }, { remove }) => {
575
+ const visitor$7 = ({ schema, key, attribute }, { remove }) => {
1200
576
  if (!attribute) {
1201
577
  return;
1202
578
  }
1203
- const isPrivate = attribute.private === true || isPrivateAttribute(schema, key2);
579
+ const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);
1204
580
  if (isPrivate) {
1205
- remove(key2);
581
+ remove(key);
1206
582
  }
1207
583
  };
1208
584
  const ACTIONS_TO_VERIFY$1 = ["find"];
1209
585
  const { CREATED_BY_ATTRIBUTE: CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE: UPDATED_BY_ATTRIBUTE$1 } = constants$1;
1210
- const removeRestrictedRelations = (auth) => async ({ data, key: key2, attribute, schema }, { remove, set }) => {
586
+ const removeRestrictedRelations = (auth) => async ({ data, key, attribute, schema }, { remove, set }) => {
1211
587
  if (!attribute) {
1212
588
  return;
1213
589
  }
@@ -1217,7 +593,7 @@ const removeRestrictedRelations = (auth) => async ({ data, key: key2, attribute,
1217
593
  }
1218
594
  const handleMorphRelation = async () => {
1219
595
  const newMorphValue = [];
1220
- for (const element of data[key2]) {
596
+ for (const element of data[key]) {
1221
597
  const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${element.__type}.${action}`);
1222
598
  const isAllowed = await hasAccessToSomeScopes$1(scopes, auth);
1223
599
  if (isAllowed) {
@@ -1225,19 +601,19 @@ const removeRestrictedRelations = (auth) => async ({ data, key: key2, attribute,
1225
601
  }
1226
602
  }
1227
603
  if (newMorphValue.length === 0) {
1228
- remove(key2);
604
+ remove(key);
1229
605
  } else {
1230
- set(key2, newMorphValue);
606
+ set(key, newMorphValue);
1231
607
  }
1232
608
  };
1233
609
  const handleRegularRelation = async () => {
1234
610
  const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${attribute.target}.${action}`);
1235
611
  const isAllowed = await hasAccessToSomeScopes$1(scopes, auth);
1236
612
  if (!isAllowed) {
1237
- remove(key2);
613
+ remove(key);
1238
614
  }
1239
615
  };
1240
- const isCreatorRelation = [CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE$1].includes(key2);
616
+ const isCreatorRelation = [CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE$1].includes(key);
1241
617
  if (isMorphToRelationalAttribute(attribute)) {
1242
618
  await handleMorphRelation();
1243
619
  return;
@@ -1258,17 +634,17 @@ const hasAccessToSomeScopes$1 = async (scopes, auth) => {
1258
634
  }
1259
635
  return false;
1260
636
  };
1261
- const visitor$5 = ({ key: key2, attribute }, { remove }) => {
637
+ const visitor$6 = ({ key, attribute }, { remove }) => {
1262
638
  if (isMorphToRelationalAttribute(attribute)) {
1263
- remove(key2);
639
+ remove(key);
1264
640
  }
1265
641
  };
1266
- const visitor$4 = ({ key: key2, attribute }, { remove }) => {
642
+ const visitor$5 = ({ key, attribute }, { remove }) => {
1267
643
  if (isDynamicZoneAttribute(attribute)) {
1268
- remove(key2);
644
+ remove(key);
1269
645
  }
1270
646
  };
1271
- const removeDisallowedFields = (allowedFields = null) => ({ key: key2, path: { attribute: path } }, { remove }) => {
647
+ const removeDisallowedFields = (allowedFields = null) => ({ key, path: { attribute: path } }, { remove }) => {
1272
648
  if (allowedFields === null) {
1273
649
  return;
1274
650
  }
@@ -1287,17 +663,17 @@ const removeDisallowedFields = (allowedFields = null) => ({ key: key2, path: { a
1287
663
  if (isPathAllowed) {
1288
664
  return;
1289
665
  }
1290
- remove(key2);
666
+ remove(key);
1291
667
  };
1292
668
  const getContainedPaths$1 = (path) => {
1293
669
  const parts = fp.toPath(path);
1294
- return parts.reduce((acc2, value2, index2, list) => {
1295
- return [...acc2, list.slice(0, index2 + 1).join(".")];
670
+ return parts.reduce((acc, value, index2, list) => {
671
+ return [...acc, list.slice(0, index2 + 1).join(".")];
1296
672
  }, []);
1297
673
  };
1298
- const removeRestrictedFields = (restrictedFields = null) => ({ key: key2, path: { attribute: path } }, { remove }) => {
674
+ const removeRestrictedFields = (restrictedFields = null) => ({ key, path: { attribute: path } }, { remove }) => {
1299
675
  if (restrictedFields === null) {
1300
- remove(key2);
676
+ remove(key);
1301
677
  return;
1302
678
  }
1303
679
  if (!(fp.isArray(restrictedFields) && restrictedFields.every(fp.isString))) {
@@ -1306,23 +682,33 @@ const removeRestrictedFields = (restrictedFields = null) => ({ key: key2, path:
1306
682
  );
1307
683
  }
1308
684
  if (restrictedFields.includes(path)) {
1309
- remove(key2);
685
+ remove(key);
1310
686
  return;
1311
687
  }
1312
688
  const isRestrictedNested = restrictedFields.some(
1313
689
  (allowedPath) => path?.toString().startsWith(`${allowedPath}.`)
1314
690
  );
1315
691
  if (isRestrictedNested) {
1316
- remove(key2);
692
+ remove(key);
693
+ }
694
+ };
695
+ const visitor$4 = ({ schema, key, value }, { set }) => {
696
+ if (key === "" && value === "*") {
697
+ const { attributes } = schema;
698
+ const newPopulateQuery = Object.entries(attributes).filter(
699
+ ([, attribute]) => ["relation", "component", "media", "dynamiczone"].includes(attribute.type)
700
+ ).reduce((acc, [key2]) => ({ ...acc, [key2]: true }), {});
701
+ set("", newPopulateQuery);
1317
702
  }
1318
703
  };
1319
704
  const visitors$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1320
705
  __proto__: null,
706
+ expandWildcardPopulate: visitor$4,
1321
707
  removeDisallowedFields,
1322
- removeDynamicZones: visitor$4,
1323
- removeMorphToRelations: visitor$5,
1324
- removePassword: visitor$7,
1325
- removePrivate: visitor$6,
708
+ removeDynamicZones: visitor$5,
709
+ removeMorphToRelations: visitor$6,
710
+ removePassword: visitor$8,
711
+ removePrivate: visitor$7,
1326
712
  removeRestrictedFields,
1327
713
  removeRestrictedRelations
1328
714
  }, Symbol.toStringTag, { value: "Module" }));
@@ -1359,85 +745,85 @@ const traverseEntity = async (visitor2, options, entity) => {
1359
745
  const visitorUtils = createVisitorUtils({ data: copy });
1360
746
  const keys = Object.keys(copy);
1361
747
  for (let i = 0; i < keys.length; i += 1) {
1362
- const key2 = keys[i];
1363
- const attribute = schema.attributes[key2];
748
+ const key = keys[i];
749
+ const attribute = schema.attributes[key];
1364
750
  if (fp.isNil(attribute)) {
1365
751
  continue;
1366
752
  }
1367
753
  const newPath = { ...path };
1368
- newPath.raw = fp.isNil(path.raw) ? key2 : `${path.raw}.${key2}`;
754
+ newPath.raw = fp.isNil(path.raw) ? key : `${path.raw}.${key}`;
1369
755
  if (!fp.isNil(attribute)) {
1370
- newPath.attribute = fp.isNil(path.attribute) ? key2 : `${path.attribute}.${key2}`;
756
+ newPath.attribute = fp.isNil(path.attribute) ? key : `${path.attribute}.${key}`;
1371
757
  }
1372
758
  const visitorOptions = {
1373
759
  data: copy,
1374
760
  schema,
1375
- key: key2,
1376
- value: copy[key2],
761
+ key,
762
+ value: copy[key],
1377
763
  attribute,
1378
764
  path: newPath
1379
765
  };
1380
766
  await visitor2(visitorOptions, visitorUtils);
1381
- const value2 = copy[key2];
1382
- if (fp.isNil(value2)) {
767
+ const value = copy[key];
768
+ if (fp.isNil(value)) {
1383
769
  continue;
1384
770
  }
1385
771
  if (isRelationalAttribute(attribute)) {
1386
772
  const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
1387
773
  const method = isMorphRelation ? traverseMorphRelationTarget : traverseRelationTarget(strapi.getModel(attribute.target));
1388
- if (fp.isArray(value2)) {
1389
- const res = new Array(value2.length);
1390
- for (let i2 = 0; i2 < value2.length; i2 += 1) {
1391
- res[i2] = await method(visitor2, newPath, value2[i2]);
774
+ if (fp.isArray(value)) {
775
+ const res = new Array(value.length);
776
+ for (let i2 = 0; i2 < value.length; i2 += 1) {
777
+ res[i2] = await method(visitor2, newPath, value[i2]);
1392
778
  }
1393
- copy[key2] = res;
779
+ copy[key] = res;
1394
780
  } else {
1395
- copy[key2] = await method(visitor2, newPath, value2);
781
+ copy[key] = await method(visitor2, newPath, value);
1396
782
  }
1397
783
  continue;
1398
784
  }
1399
785
  if (isMediaAttribute(attribute)) {
1400
- if (fp.isArray(value2)) {
1401
- const res = new Array(value2.length);
1402
- for (let i2 = 0; i2 < value2.length; i2 += 1) {
1403
- res[i2] = await traverseMediaTarget(visitor2, newPath, value2[i2]);
786
+ if (fp.isArray(value)) {
787
+ const res = new Array(value.length);
788
+ for (let i2 = 0; i2 < value.length; i2 += 1) {
789
+ res[i2] = await traverseMediaTarget(visitor2, newPath, value[i2]);
1404
790
  }
1405
- copy[key2] = res;
791
+ copy[key] = res;
1406
792
  } else {
1407
- copy[key2] = await traverseMediaTarget(visitor2, newPath, value2);
793
+ copy[key] = await traverseMediaTarget(visitor2, newPath, value);
1408
794
  }
1409
795
  continue;
1410
796
  }
1411
797
  if (attribute.type === "component") {
1412
798
  const targetSchema = strapi.getModel(attribute.component);
1413
- if (fp.isArray(value2)) {
1414
- const res = new Array(value2.length);
1415
- for (let i2 = 0; i2 < value2.length; i2 += 1) {
1416
- res[i2] = await traverseComponent(visitor2, newPath, targetSchema, value2[i2]);
799
+ if (fp.isArray(value)) {
800
+ const res = new Array(value.length);
801
+ for (let i2 = 0; i2 < value.length; i2 += 1) {
802
+ res[i2] = await traverseComponent(visitor2, newPath, targetSchema, value[i2]);
1417
803
  }
1418
- copy[key2] = res;
804
+ copy[key] = res;
1419
805
  } else {
1420
- copy[key2] = await traverseComponent(visitor2, newPath, targetSchema, value2);
806
+ copy[key] = await traverseComponent(visitor2, newPath, targetSchema, value);
1421
807
  }
1422
808
  continue;
1423
809
  }
1424
- if (attribute.type === "dynamiczone" && fp.isArray(value2)) {
1425
- const res = new Array(value2.length);
1426
- for (let i2 = 0; i2 < value2.length; i2 += 1) {
1427
- res[i2] = await visitDynamicZoneEntry(visitor2, newPath, value2[i2]);
810
+ if (attribute.type === "dynamiczone" && fp.isArray(value)) {
811
+ const res = new Array(value.length);
812
+ for (let i2 = 0; i2 < value.length; i2 += 1) {
813
+ res[i2] = await visitDynamicZoneEntry(visitor2, newPath, value[i2]);
1428
814
  }
1429
- copy[key2] = res;
815
+ copy[key] = res;
1430
816
  continue;
1431
817
  }
1432
818
  }
1433
819
  return copy;
1434
820
  };
1435
821
  const createVisitorUtils = ({ data }) => ({
1436
- remove(key2) {
1437
- delete data[key2];
822
+ remove(key) {
823
+ delete data[key];
1438
824
  },
1439
- set(key2, value2) {
1440
- data[key2] = value2;
825
+ set(key, value) {
826
+ data[key] = value;
1441
827
  }
1442
828
  });
1443
829
  const traverseEntity$1 = fp.curry(traverseEntity);
@@ -1466,37 +852,37 @@ const traverseFactory = () => {
1466
852
  }
1467
853
  let out = utils2.transform(data);
1468
854
  const keys = utils2.keys(out);
1469
- for (const key2 of keys) {
1470
- const attribute = schema?.attributes?.[key2] ?? // FIX: Needed to not break existing behavior on the API.
855
+ for (const key of keys) {
856
+ const attribute = schema?.attributes?.[key] ?? // FIX: Needed to not break existing behavior on the API.
1471
857
  // It looks for the attribute in the DB metadata when the key is in snake_case
1472
- schema?.attributes?.[strapi.db.metadata.get(schema?.uid).columnToAttribute[key2]];
858
+ schema?.attributes?.[strapi.db.metadata.get(schema?.uid).columnToAttribute[key]];
1473
859
  const newPath = { ...path };
1474
- newPath.raw = fp.isNil(path.raw) ? key2 : `${path.raw}.${key2}`;
860
+ newPath.raw = fp.isNil(path.raw) ? key : `${path.raw}.${key}`;
1475
861
  if (!fp.isNil(attribute)) {
1476
- newPath.attribute = fp.isNil(path.attribute) ? key2 : `${path.attribute}.${key2}`;
862
+ newPath.attribute = fp.isNil(path.attribute) ? key : `${path.attribute}.${key}`;
1477
863
  }
1478
864
  const visitorOptions = {
1479
- key: key2,
1480
- value: utils2.get(key2, out),
865
+ key,
866
+ value: utils2.get(key, out),
1481
867
  attribute,
1482
868
  schema,
1483
869
  path: newPath,
1484
870
  data: out
1485
871
  };
1486
872
  const transformUtils = {
1487
- remove(key22) {
1488
- out = utils2.remove(key22, out);
873
+ remove(key2) {
874
+ out = utils2.remove(key2, out);
1489
875
  },
1490
- set(key22, value22) {
1491
- out = utils2.set(key22, value22, out);
876
+ set(key2, value2) {
877
+ out = utils2.set(key2, value2, out);
1492
878
  },
1493
879
  recurse: traverse
1494
880
  };
1495
881
  await visitor2(visitorOptions, fp.pick(["remove", "set"], transformUtils));
1496
- const value2 = utils2.get(key2, out);
882
+ const value = utils2.get(key, out);
1497
883
  const createContext = () => ({
1498
- key: key2,
1499
- value: value2,
884
+ key,
885
+ value,
1500
886
  attribute,
1501
887
  schema,
1502
888
  path: newPath,
@@ -1555,7 +941,7 @@ const traverseFactory = () => {
1555
941
  }
1556
942
  };
1557
943
  };
1558
- const isObj$2 = (value2) => fp.isObject(value2);
944
+ const isObj$2 = (value) => fp.isObject(value);
1559
945
  const filters = traverseFactory().intercept(
1560
946
  // Intercept filters arrays and apply the traversal to each one individually
1561
947
  fp.isArray,
@@ -1576,50 +962,50 @@ const filters = traverseFactory().intercept(
1576
962
  }
1577
963
  ).parse(isObj$2, () => ({
1578
964
  transform: fp.cloneDeep,
1579
- remove(key2, data) {
1580
- return fp.omit(key2, data);
965
+ remove(key, data) {
966
+ return fp.omit(key, data);
1581
967
  },
1582
- set(key2, value2, data) {
1583
- return { ...data, [key2]: value2 };
968
+ set(key, value, data) {
969
+ return { ...data, [key]: value };
1584
970
  },
1585
971
  keys(data) {
1586
972
  return Object.keys(data);
1587
973
  },
1588
- get(key2, data) {
1589
- return data[key2];
974
+ get(key, data) {
975
+ return data[key];
1590
976
  }
1591
- })).ignore(({ value: value2 }) => fp.isNil(value2)).on(
977
+ })).ignore(({ value }) => fp.isNil(value)).on(
1592
978
  ({ attribute }) => fp.isNil(attribute),
1593
- async ({ key: key2, visitor: visitor2, path, value: value2, schema }, { set, recurse }) => {
1594
- set(key2, await recurse(visitor2, { schema, path }, value2));
979
+ async ({ key, visitor: visitor2, path, value, schema }, { set, recurse }) => {
980
+ set(key, await recurse(visitor2, { schema, path }, value));
1595
981
  }
1596
- ).onRelation(async ({ key: key2, attribute, visitor: visitor2, path, value: value2 }, { set, recurse }) => {
982
+ ).onRelation(async ({ key, attribute, visitor: visitor2, path, value }, { set, recurse }) => {
1597
983
  const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
1598
984
  if (isMorphRelation) {
1599
985
  return;
1600
986
  }
1601
987
  const targetSchemaUID = attribute.target;
1602
988
  const targetSchema = strapi.getModel(targetSchemaUID);
1603
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1604
- set(key2, newValue);
1605
- }).onComponent(async ({ key: key2, attribute, visitor: visitor2, path, value: value2 }, { set, recurse }) => {
989
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
990
+ set(key, newValue);
991
+ }).onComponent(async ({ key, attribute, visitor: visitor2, path, value }, { set, recurse }) => {
1606
992
  const targetSchema = strapi.getModel(attribute.component);
1607
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1608
- set(key2, newValue);
1609
- }).onMedia(async ({ key: key2, visitor: visitor2, path, value: value2 }, { set, recurse }) => {
993
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
994
+ set(key, newValue);
995
+ }).onMedia(async ({ key, visitor: visitor2, path, value }, { set, recurse }) => {
1610
996
  const targetSchemaUID = "plugin::upload.file";
1611
997
  const targetSchema = strapi.getModel(targetSchemaUID);
1612
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1613
- set(key2, newValue);
998
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
999
+ set(key, newValue);
1614
1000
  });
1615
1001
  const traverseQueryFilters = fp.curry(filters.traverse);
1616
1002
  const ORDERS = { asc: "asc", desc: "desc" };
1617
1003
  const ORDER_VALUES = Object.values(ORDERS);
1618
- const isSortOrder = (value2) => ORDER_VALUES.includes(value2.toLowerCase());
1619
- const isStringArray$3 = (value2) => Array.isArray(value2) && value2.every(fp.isString);
1620
- const isObjectArray = (value2) => Array.isArray(value2) && value2.every(fp.isObject);
1621
- const isNestedSorts = (value2) => fp.isString(value2) && value2.split(",").length > 1;
1622
- const isObj$1 = (value2) => fp.isObject(value2);
1004
+ const isSortOrder = (value) => ORDER_VALUES.includes(value.toLowerCase());
1005
+ const isStringArray$3 = (value) => Array.isArray(value) && value.every(fp.isString);
1006
+ const isObjectArray = (value) => Array.isArray(value) && value.every(fp.isObject);
1007
+ const isNestedSorts = (value) => fp.isString(value) && value.split(",").length > 1;
1008
+ const isObj$1 = (value) => fp.isObject(value);
1623
1009
  const sort = traverseFactory().intercept(
1624
1010
  // String with chained sorts (foo,bar,foobar) => split, map(recurse), then recompose
1625
1011
  isNestedSorts,
@@ -1650,215 +1036,234 @@ const sort = traverseFactory().intercept(
1650
1036
  if (parts.length === 0) {
1651
1037
  return void 0;
1652
1038
  }
1653
- return parts.reduce((acc2, part) => {
1039
+ return parts.reduce((acc, part) => {
1654
1040
  if (fp.isEmpty(part)) {
1655
- return acc2;
1041
+ return acc;
1656
1042
  }
1657
- if (acc2 === "") {
1043
+ if (acc === "") {
1658
1044
  return part;
1659
1045
  }
1660
- return isSortOrder(part) ? `${acc2}:${part}` : `${acc2}.${part}`;
1046
+ return isSortOrder(part) ? `${acc}:${part}` : `${acc}.${part}`;
1661
1047
  }, "");
1662
1048
  };
1663
1049
  return {
1664
1050
  transform: fp.trim,
1665
- remove(key2, data) {
1051
+ remove(key, data) {
1666
1052
  const [root] = tokenize(data);
1667
- return root === key2 ? void 0 : data;
1053
+ return root === key ? void 0 : data;
1668
1054
  },
1669
- set(key2, value2, data) {
1055
+ set(key, value, data) {
1670
1056
  const [root] = tokenize(data);
1671
- if (root !== key2) {
1057
+ if (root !== key) {
1672
1058
  return data;
1673
1059
  }
1674
- return fp.isNil(value2) ? root : `${root}.${value2}`;
1060
+ return fp.isNil(value) ? root : `${root}.${value}`;
1675
1061
  },
1676
1062
  keys(data) {
1677
1063
  const v = fp.first(tokenize(data));
1678
1064
  return v ? [v] : [];
1679
1065
  },
1680
- get(key2, data) {
1066
+ get(key, data) {
1681
1067
  const [root, ...rest] = tokenize(data);
1682
- return key2 === root ? recompose(rest) : void 0;
1068
+ return key === root ? recompose(rest) : void 0;
1683
1069
  }
1684
1070
  };
1685
1071
  }).parse(isObj$1, () => ({
1686
1072
  transform: fp.cloneDeep,
1687
- remove(key2, data) {
1688
- const { [key2]: ignored, ...rest } = data;
1073
+ remove(key, data) {
1074
+ const { [key]: ignored, ...rest } = data;
1689
1075
  return rest;
1690
1076
  },
1691
- set(key2, value2, data) {
1692
- return { ...data, [key2]: value2 };
1077
+ set(key, value, data) {
1078
+ return { ...data, [key]: value };
1693
1079
  },
1694
1080
  keys(data) {
1695
1081
  return Object.keys(data);
1696
1082
  },
1697
- get(key2, data) {
1698
- return data[key2];
1083
+ get(key, data) {
1084
+ return data[key];
1699
1085
  }
1700
- })).onRelation(async ({ key: key2, value: value2, attribute, visitor: visitor2, path }, { set, recurse }) => {
1086
+ })).onRelation(async ({ key, value, attribute, visitor: visitor2, path }, { set, recurse }) => {
1701
1087
  const isMorphRelation = attribute.relation.toLowerCase().startsWith("morph");
1702
1088
  if (isMorphRelation) {
1703
1089
  return;
1704
1090
  }
1705
1091
  const targetSchemaUID = attribute.target;
1706
1092
  const targetSchema = strapi.getModel(targetSchemaUID);
1707
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1708
- set(key2, newValue);
1709
- }).onMedia(async ({ key: key2, path, visitor: visitor2, value: value2 }, { recurse, set }) => {
1093
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
1094
+ set(key, newValue);
1095
+ }).onMedia(async ({ key, path, visitor: visitor2, value }, { recurse, set }) => {
1710
1096
  const targetSchemaUID = "plugin::upload.file";
1711
1097
  const targetSchema = strapi.getModel(targetSchemaUID);
1712
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1713
- set(key2, newValue);
1714
- }).onComponent(async ({ key: key2, value: value2, visitor: visitor2, path, attribute }, { recurse, set }) => {
1098
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
1099
+ set(key, newValue);
1100
+ }).onComponent(async ({ key, value, visitor: visitor2, path, attribute }, { recurse, set }) => {
1715
1101
  const targetSchema = strapi.getModel(attribute.component);
1716
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1717
- set(key2, newValue);
1102
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
1103
+ set(key, newValue);
1718
1104
  });
1719
1105
  const traverseQuerySort = fp.curry(sort.traverse);
1720
1106
  const isKeyword = (keyword) => {
1721
- return ({ key: key2, attribute }) => {
1722
- return !attribute && keyword === key2;
1107
+ return ({ key, attribute }) => {
1108
+ return !attribute && keyword === key;
1723
1109
  };
1724
1110
  };
1725
- const isStringArray$2 = (value2) => fp.isArray(value2) && value2.every(fp.isString);
1726
- const isWildCardConstant = (value2) => value2 === "*";
1727
- const isObj = (value2) => fp.isObject(value2);
1111
+ const isStringArray$2 = (value) => fp.isArray(value) && value.every(fp.isString);
1112
+ const isObj = (value) => fp.isObject(value);
1728
1113
  const populate = traverseFactory().intercept(isStringArray$2, async (visitor2, options, populate2, { recurse }) => {
1729
1114
  const visitedPopulate = await Promise.all(
1730
1115
  populate2.map((nestedPopulate) => recurse(visitor2, options, nestedPopulate))
1731
1116
  );
1732
1117
  return visitedPopulate.filter((item) => !fp.isNil(item));
1733
- }).intercept(isWildCardConstant, (visitor2, options, _data, { recurse }) => {
1734
- const attributes = options.schema?.attributes;
1735
- if (!attributes) {
1736
- return "*";
1737
- }
1738
- const parsedPopulate = Object.entries(attributes).filter(([, value2]) => ["relation", "component", "dynamiczone", "media"].includes(value2.type)).reduce((acc2, [key2]) => ({ ...acc2, [key2]: true }), {});
1739
- return recurse(visitor2, options, parsedPopulate);
1740
- }).parse(fp.isString, () => {
1118
+ }).parse(
1119
+ (value) => value === "*",
1120
+ () => ({
1121
+ /**
1122
+ * Since value is '*', we don't need to transform it
1123
+ */
1124
+ transform: fp.identity,
1125
+ /**
1126
+ * '*' isn't a key/value structure, so regardless
1127
+ * of the given key, it returns the data ('*')
1128
+ */
1129
+ get: (_key, data) => data,
1130
+ /**
1131
+ * '*' isn't a key/value structure, so regardless
1132
+ * of the given `key`, use `value` as the new `data`
1133
+ */
1134
+ set: (_key, value) => value,
1135
+ /**
1136
+ * '*' isn't a key/value structure, but we need to simulate at least one to enable
1137
+ * the data traversal. We're using '' since it represents a falsy string value
1138
+ */
1139
+ keys: fp.constant([""]),
1140
+ /**
1141
+ * Removing '*' means setting it to undefined, regardless of the given key
1142
+ */
1143
+ remove: fp.constant(void 0)
1144
+ })
1145
+ ).parse(fp.isString, () => {
1741
1146
  const tokenize = fp.split(".");
1742
1147
  const recompose = fp.join(".");
1743
1148
  return {
1744
1149
  transform: fp.trim,
1745
- remove(key2, data) {
1150
+ remove(key, data) {
1746
1151
  const [root] = tokenize(data);
1747
- return root === key2 ? void 0 : data;
1152
+ return root === key ? void 0 : data;
1748
1153
  },
1749
- set(key2, value2, data) {
1154
+ set(key, value, data) {
1750
1155
  const [root] = tokenize(data);
1751
- if (root !== key2) {
1156
+ if (root !== key) {
1752
1157
  return data;
1753
1158
  }
1754
- return fp.isNil(value2) || fp.isEmpty(value2) ? root : `${root}.${value2}`;
1159
+ return fp.isNil(value) || fp.isEmpty(value) ? root : `${root}.${value}`;
1755
1160
  },
1756
1161
  keys(data) {
1757
1162
  const v = fp.first(tokenize(data));
1758
1163
  return v ? [v] : [];
1759
1164
  },
1760
- get(key2, data) {
1165
+ get(key, data) {
1761
1166
  const [root, ...rest] = tokenize(data);
1762
- return key2 === root ? recompose(rest) : void 0;
1167
+ return key === root ? recompose(rest) : void 0;
1763
1168
  }
1764
1169
  };
1765
1170
  }).parse(isObj, () => ({
1766
1171
  transform: fp.cloneDeep,
1767
- remove(key2, data) {
1768
- const { [key2]: ignored, ...rest } = data;
1172
+ remove(key, data) {
1173
+ const { [key]: ignored, ...rest } = data;
1769
1174
  return rest;
1770
1175
  },
1771
- set(key2, value2, data) {
1772
- return { ...data, [key2]: value2 };
1176
+ set(key, value, data) {
1177
+ return { ...data, [key]: value };
1773
1178
  },
1774
1179
  keys(data) {
1775
1180
  return Object.keys(data);
1776
1181
  },
1777
- get(key2, data) {
1778
- return data[key2];
1182
+ get(key, data) {
1183
+ return data[key];
1779
1184
  }
1780
- })).ignore(({ key: key2, attribute }) => {
1781
- return ["sort", "filters", "fields"].includes(key2) && !attribute;
1185
+ })).ignore(({ key, attribute }) => {
1186
+ return ["sort", "filters", "fields"].includes(key) && !attribute;
1782
1187
  }).on(
1783
1188
  // Handle recursion on populate."populate"
1784
1189
  isKeyword("populate"),
1785
- async ({ key: key2, visitor: visitor2, path, value: value2, schema }, { set, recurse }) => {
1786
- const newValue = await recurse(visitor2, { schema, path }, value2);
1787
- set(key2, newValue);
1190
+ async ({ key, visitor: visitor2, path, value, schema }, { set, recurse }) => {
1191
+ const newValue = await recurse(visitor2, { schema, path }, value);
1192
+ set(key, newValue);
1788
1193
  }
1789
- ).on(isKeyword("on"), async ({ key: key2, visitor: visitor2, path, value: value2 }, { set, recurse }) => {
1194
+ ).on(isKeyword("on"), async ({ key, visitor: visitor2, path, value }, { set, recurse }) => {
1790
1195
  const newOn = {};
1791
- if (!isObj(value2)) {
1196
+ if (!isObj(value)) {
1792
1197
  return;
1793
1198
  }
1794
- for (const [uid, subPopulate] of Object.entries(value2)) {
1199
+ for (const [uid, subPopulate] of Object.entries(value)) {
1795
1200
  const model = strapi.getModel(uid);
1796
1201
  const newPath = { ...path, raw: `${path.raw}[${uid}]` };
1797
1202
  newOn[uid] = await recurse(visitor2, { schema: model, path: newPath }, subPopulate);
1798
1203
  }
1799
- set(key2, newOn);
1800
- }).onRelation(async ({ key: key2, value: value2, attribute, visitor: visitor2, path, schema }, { set, recurse }) => {
1801
- if (fp.isNil(value2)) {
1204
+ set(key, newOn);
1205
+ }).onRelation(async ({ key, value, attribute, visitor: visitor2, path, schema }, { set, recurse }) => {
1206
+ if (fp.isNil(value)) {
1802
1207
  return;
1803
1208
  }
1804
1209
  if (isMorphToRelationalAttribute(attribute)) {
1805
- if (!fp.isObject(value2) || !("on" in value2 && fp.isObject(value2?.on))) {
1210
+ if (!fp.isObject(value) || !("on" in value && fp.isObject(value?.on))) {
1806
1211
  return;
1807
1212
  }
1808
- const newValue2 = await recurse(visitor2, { schema, path }, { on: value2?.on });
1809
- set(key2, { on: newValue2 });
1213
+ const newValue2 = await recurse(visitor2, { schema, path }, { on: value?.on });
1214
+ set(key, { on: newValue2 });
1810
1215
  }
1811
1216
  const targetSchemaUID = attribute.target;
1812
1217
  const targetSchema = strapi.getModel(targetSchemaUID);
1813
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1814
- set(key2, newValue);
1815
- }).onMedia(async ({ key: key2, path, visitor: visitor2, value: value2 }, { recurse, set }) => {
1816
- if (fp.isNil(value2)) {
1218
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
1219
+ set(key, newValue);
1220
+ }).onMedia(async ({ key, path, visitor: visitor2, value }, { recurse, set }) => {
1221
+ if (fp.isNil(value)) {
1817
1222
  return;
1818
1223
  }
1819
1224
  const targetSchemaUID = "plugin::upload.file";
1820
1225
  const targetSchema = strapi.getModel(targetSchemaUID);
1821
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1822
- set(key2, newValue);
1823
- }).onComponent(async ({ key: key2, value: value2, visitor: visitor2, path, attribute }, { recurse, set }) => {
1824
- if (fp.isNil(value2)) {
1226
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
1227
+ set(key, newValue);
1228
+ }).onComponent(async ({ key, value, visitor: visitor2, path, attribute }, { recurse, set }) => {
1229
+ if (fp.isNil(value)) {
1825
1230
  return;
1826
1231
  }
1827
1232
  const targetSchema = strapi.getModel(attribute.component);
1828
- const newValue = await recurse(visitor2, { schema: targetSchema, path }, value2);
1829
- set(key2, newValue);
1830
- }).onDynamicZone(async ({ key: key2, value: value2, attribute, schema, visitor: visitor2, path }, { set, recurse }) => {
1831
- if (fp.isNil(value2)) {
1233
+ const newValue = await recurse(visitor2, { schema: targetSchema, path }, value);
1234
+ set(key, newValue);
1235
+ }).onDynamicZone(async ({ key, value, attribute, schema, visitor: visitor2, path }, { set, recurse }) => {
1236
+ if (fp.isNil(value)) {
1832
1237
  return;
1833
1238
  }
1834
- if (fp.isObject(value2)) {
1239
+ if (fp.isObject(value)) {
1835
1240
  const { components } = attribute;
1836
1241
  const newValue = {};
1837
- let newProperties = fp.omit("on", value2);
1242
+ let newProperties = fp.omit("on", value);
1838
1243
  for (const componentUID of components) {
1839
1244
  const componentSchema = strapi.getModel(componentUID);
1840
- const properties = await recurse(visitor2, { schema: componentSchema, path }, value2);
1245
+ const properties = await recurse(visitor2, { schema: componentSchema, path }, value);
1841
1246
  newProperties = fp.merge(newProperties, properties);
1842
1247
  }
1843
1248
  Object.assign(newValue, newProperties);
1844
- if ("on" in value2 && value2.on) {
1845
- const newOn = await recurse(visitor2, { schema, path }, { on: value2.on });
1249
+ if ("on" in value && value.on) {
1250
+ const newOn = await recurse(visitor2, { schema, path }, { on: value.on });
1846
1251
  Object.assign(newValue, newOn);
1847
1252
  }
1848
- set(key2, newValue);
1253
+ set(key, newValue);
1849
1254
  } else {
1850
- const newValue = await recurse(visitor2, { schema, path }, value2);
1851
- set(key2, newValue);
1255
+ const newValue = await recurse(visitor2, { schema, path }, value);
1256
+ set(key, newValue);
1852
1257
  }
1853
1258
  });
1854
1259
  const traverseQueryPopulate = fp.curry(populate.traverse);
1855
- const isStringArray$1 = (value2) => fp.isArray(value2) && value2.every(fp.isString);
1260
+ const isStringArray$1 = (value) => fp.isArray(value) && value.every(fp.isString);
1856
1261
  const fields = traverseFactory().intercept(isStringArray$1, async (visitor2, options, fields2, { recurse }) => {
1857
1262
  return Promise.all(fields2.map((field) => recurse(visitor2, options, field)));
1858
- }).intercept((value2) => fp.eq("*", value2), fp.constant("*")).parse(fp.isString, () => ({
1263
+ }).intercept((value) => fp.eq("*", value), fp.constant("*")).parse(fp.isString, () => ({
1859
1264
  transform: fp.trim,
1860
- remove(key2, data) {
1861
- return data === key2 ? void 0 : data;
1265
+ remove(key, data) {
1266
+ return data === key ? void 0 : data;
1862
1267
  },
1863
1268
  set(_key, _value, data) {
1864
1269
  return data;
@@ -1866,8 +1271,8 @@ const fields = traverseFactory().intercept(isStringArray$1, async (visitor2, opt
1866
1271
  keys(data) {
1867
1272
  return [data];
1868
1273
  },
1869
- get(key2, data) {
1870
- return key2 === data ? data : void 0;
1274
+ get(key, data) {
1275
+ return key === data ? data : void 0;
1871
1276
  }
1872
1277
  }));
1873
1278
  const traverseQueryFields = fp.curry(fields.traverse);
@@ -1926,31 +1331,32 @@ const OPERATORS = {
1926
1331
  array: ARRAY_OPERATORS
1927
1332
  };
1928
1333
  const OPERATORS_LOWERCASE = Object.fromEntries(
1929
- Object.entries(OPERATORS).map(([key2, values]) => [
1930
- key2,
1931
- values.map((value2) => value2.toLowerCase())
1334
+ Object.entries(OPERATORS).map(([key, values]) => [
1335
+ key,
1336
+ values.map((value) => value.toLowerCase())
1932
1337
  ])
1933
1338
  );
1934
- const isObjKey = (key2, obj2) => {
1935
- return key2 in obj2;
1339
+ const isObjKey = (key, obj) => {
1340
+ return key in obj;
1936
1341
  };
1937
- const isOperatorOfType = (type, key2, ignoreCase = false) => {
1342
+ const isOperatorOfType = (type, key, ignoreCase = false) => {
1938
1343
  if (ignoreCase) {
1939
- return OPERATORS_LOWERCASE[type]?.includes(key2.toLowerCase()) ?? false;
1344
+ return OPERATORS_LOWERCASE[type]?.includes(key.toLowerCase()) ?? false;
1940
1345
  }
1941
1346
  if (isObjKey(type, OPERATORS)) {
1942
- return OPERATORS[type]?.includes(key2) ?? false;
1347
+ return OPERATORS[type]?.includes(key) ?? false;
1943
1348
  }
1944
1349
  return false;
1945
1350
  };
1946
- const isOperator = (key2, ignoreCase = false) => {
1947
- return Object.keys(OPERATORS).some((type) => isOperatorOfType(type, key2, ignoreCase));
1351
+ const isOperator = (key, ignoreCase = false) => {
1352
+ return Object.keys(OPERATORS).some((type) => isOperatorOfType(type, key, ignoreCase));
1948
1353
  };
1354
+ const { ID_ATTRIBUTE: ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE: DOC_ID_ATTRIBUTE$3 } = constants$1;
1949
1355
  const sanitizePasswords = (schema) => async (entity) => {
1950
1356
  if (!schema) {
1951
1357
  throw new Error("Missing schema in sanitizePasswords");
1952
1358
  }
1953
- return traverseEntity$1(visitor$7, { schema }, entity);
1359
+ return traverseEntity$1(visitor$8, { schema }, entity);
1954
1360
  };
1955
1361
  const defaultSanitizeOutput = async (schema, entity) => {
1956
1362
  if (!schema) {
@@ -1958,8 +1364,8 @@ const defaultSanitizeOutput = async (schema, entity) => {
1958
1364
  }
1959
1365
  return traverseEntity$1(
1960
1366
  (...args) => {
1367
+ visitor$8(...args);
1961
1368
  visitor$7(...args);
1962
- visitor$6(...args);
1963
1369
  },
1964
1370
  { schema },
1965
1371
  entity
@@ -1969,33 +1375,33 @@ const defaultSanitizeFilters = fp.curry((schema, filters2) => {
1969
1375
  if (!schema) {
1970
1376
  throw new Error("Missing schema in defaultSanitizeFilters");
1971
1377
  }
1972
- return pipeAsync(
1378
+ return pipe(
1973
1379
  // Remove keys that are not attributes or valid operators
1974
1380
  traverseQueryFilters(
1975
- ({ key: key2, attribute }, { remove }) => {
1381
+ ({ key, attribute }, { remove }) => {
1976
1382
  const isAttribute = !!attribute;
1977
- if (key2 === "id") {
1383
+ if ([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3].includes(key)) {
1978
1384
  return;
1979
1385
  }
1980
- if (!isAttribute && !isOperator(key2)) {
1981
- remove(key2);
1386
+ if (!isAttribute && !isOperator(key)) {
1387
+ remove(key);
1982
1388
  }
1983
1389
  },
1984
1390
  { schema }
1985
1391
  ),
1986
1392
  // Remove dynamic zones from filters
1987
- traverseQueryFilters(visitor$4, { schema }),
1988
- // Remove morpTo relations from filters
1989
1393
  traverseQueryFilters(visitor$5, { schema }),
1394
+ // Remove morpTo relations from filters
1395
+ traverseQueryFilters(visitor$6, { schema }),
1990
1396
  // Remove passwords from filters
1991
- traverseQueryFilters(visitor$7, { schema }),
1397
+ traverseQueryFilters(visitor$8, { schema }),
1992
1398
  // Remove private from filters
1993
- traverseQueryFilters(visitor$6, { schema }),
1399
+ traverseQueryFilters(visitor$7, { schema }),
1994
1400
  // Remove empty objects
1995
1401
  traverseQueryFilters(
1996
- ({ key: key2, value: value2 }, { remove }) => {
1997
- if (fp.isObject(value2) && fp.isEmpty(value2)) {
1998
- remove(key2);
1402
+ ({ key, value }, { remove }) => {
1403
+ if (fp.isObject(value) && fp.isEmpty(value)) {
1404
+ remove(key);
1999
1405
  }
2000
1406
  },
2001
1407
  { schema }
@@ -2006,35 +1412,35 @@ const defaultSanitizeSort = fp.curry((schema, sort2) => {
2006
1412
  if (!schema) {
2007
1413
  throw new Error("Missing schema in defaultSanitizeSort");
2008
1414
  }
2009
- return pipeAsync(
1415
+ return pipe(
2010
1416
  // Remove non attribute keys
2011
1417
  traverseQuerySort(
2012
- ({ key: key2, attribute }, { remove }) => {
2013
- if (key2 === "id") {
1418
+ ({ key, attribute }, { remove }) => {
1419
+ if ([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3].includes(key)) {
2014
1420
  return;
2015
1421
  }
2016
1422
  if (!attribute) {
2017
- remove(key2);
1423
+ remove(key);
2018
1424
  }
2019
1425
  },
2020
1426
  { schema }
2021
1427
  ),
2022
1428
  // Remove dynamic zones from sort
2023
- traverseQuerySort(visitor$4, { schema }),
2024
- // Remove morpTo relations from sort
2025
1429
  traverseQuerySort(visitor$5, { schema }),
2026
- // Remove private from sort
1430
+ // Remove morpTo relations from sort
2027
1431
  traverseQuerySort(visitor$6, { schema }),
2028
- // Remove passwords from filters
1432
+ // Remove private from sort
2029
1433
  traverseQuerySort(visitor$7, { schema }),
1434
+ // Remove passwords from filters
1435
+ traverseQuerySort(visitor$8, { schema }),
2030
1436
  // Remove keys for empty non-scalar values
2031
1437
  traverseQuerySort(
2032
- ({ key: key2, attribute, value: value2 }, { remove }) => {
2033
- if (key2 === "id") {
1438
+ ({ key, attribute, value }, { remove }) => {
1439
+ if ([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3].includes(key)) {
2034
1440
  return;
2035
1441
  }
2036
- if (!isScalarAttribute(attribute) && fp.isEmpty(value2)) {
2037
- remove(key2);
1442
+ if (!isScalarAttribute(attribute) && fp.isEmpty(value)) {
1443
+ remove(key);
2038
1444
  }
2039
1445
  },
2040
1446
  { schema }
@@ -2045,51 +1451,55 @@ const defaultSanitizeFields = fp.curry((schema, fields2) => {
2045
1451
  if (!schema) {
2046
1452
  throw new Error("Missing schema in defaultSanitizeFields");
2047
1453
  }
2048
- return pipeAsync(
1454
+ return pipe(
2049
1455
  // Only keep scalar attributes
2050
1456
  traverseQueryFields(
2051
- ({ key: key2, attribute }, { remove }) => {
2052
- if (key2 === "id") {
1457
+ ({ key, attribute }, { remove }) => {
1458
+ if ([ID_ATTRIBUTE$3, DOC_ID_ATTRIBUTE$3].includes(key)) {
2053
1459
  return;
2054
1460
  }
2055
1461
  if (fp.isNil(attribute) || !isScalarAttribute(attribute)) {
2056
- remove(key2);
1462
+ remove(key);
2057
1463
  }
2058
1464
  },
2059
1465
  { schema }
2060
1466
  ),
2061
1467
  // Remove private fields
2062
- traverseQueryFields(visitor$6, { schema }),
2063
- // Remove password fields
2064
1468
  traverseQueryFields(visitor$7, { schema }),
1469
+ // Remove password fields
1470
+ traverseQueryFields(visitor$8, { schema }),
2065
1471
  // Remove nil values from fields array
2066
- (value2) => fp.isArray(value2) ? value2.filter((field) => !fp.isNil(field)) : value2
1472
+ (value) => fp.isArray(value) ? value.filter((field) => !fp.isNil(field)) : value
2067
1473
  )(fields2);
2068
1474
  });
2069
1475
  const defaultSanitizePopulate = fp.curry((schema, populate2) => {
2070
1476
  if (!schema) {
2071
1477
  throw new Error("Missing schema in defaultSanitizePopulate");
2072
1478
  }
2073
- return pipeAsync(
1479
+ return pipe(
1480
+ traverseQueryPopulate(visitor$4, { schema }),
2074
1481
  traverseQueryPopulate(
2075
- async ({ key: key2, value: value2, schema: schema2, attribute }, { set }) => {
1482
+ async ({ key, value, schema: schema2, attribute }, { set }) => {
2076
1483
  if (attribute) {
2077
1484
  return;
2078
1485
  }
2079
- if (key2 === "sort") {
2080
- set(key2, await defaultSanitizeSort(schema2, value2));
1486
+ if (key === "sort") {
1487
+ set(key, await defaultSanitizeSort(schema2, value));
2081
1488
  }
2082
- if (key2 === "filters") {
2083
- set(key2, await defaultSanitizeFilters(schema2, value2));
1489
+ if (key === "filters") {
1490
+ set(key, await defaultSanitizeFilters(schema2, value));
2084
1491
  }
2085
- if (key2 === "fields") {
2086
- set(key2, await defaultSanitizeFields(schema2, value2));
1492
+ if (key === "fields") {
1493
+ set(key, await defaultSanitizeFields(schema2, value));
1494
+ }
1495
+ if (key === "populate") {
1496
+ set(key, await defaultSanitizePopulate(schema2, value));
2087
1497
  }
2088
1498
  },
2089
1499
  { schema }
2090
1500
  ),
2091
1501
  // Remove private fields
2092
- traverseQueryPopulate(visitor$6, { schema })
1502
+ traverseQueryPopulate(visitor$7, { schema })
2093
1503
  )(populate2);
2094
1504
  });
2095
1505
  const sanitizers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -2112,7 +1522,8 @@ const createContentAPISanitizers = () => {
2112
1522
  const nonWritableAttributes = getNonWritableAttributes(schema);
2113
1523
  const transforms = [
2114
1524
  // Remove first level ID in inputs
2115
- fp.omit("id"),
1525
+ fp.omit(constants$1.ID_ATTRIBUTE),
1526
+ fp.omit(constants$1.DOC_ID_ATTRIBUTE),
2116
1527
  // Remove non-writable attributes
2117
1528
  traverseEntity$1(removeRestrictedFields(nonWritableAttributes), { schema })
2118
1529
  ];
@@ -2120,7 +1531,7 @@ const createContentAPISanitizers = () => {
2120
1531
  transforms.push(traverseEntity$1(removeRestrictedRelations(auth), { schema }));
2121
1532
  }
2122
1533
  strapi.sanitizers.get("content-api.input").forEach((sanitizer) => transforms.push(sanitizer(schema)));
2123
- return pipeAsync(...transforms)(data);
1534
+ return pipe(...transforms)(data);
2124
1535
  };
2125
1536
  const sanitizeOutput = async (data, schema, { auth } = {}) => {
2126
1537
  if (!schema) {
@@ -2138,7 +1549,7 @@ const createContentAPISanitizers = () => {
2138
1549
  transforms.push(traverseEntity$1(removeRestrictedRelations(auth), { schema }));
2139
1550
  }
2140
1551
  strapi.sanitizers.get("content-api.output").forEach((sanitizer) => transforms.push(sanitizer(schema)));
2141
- return pipeAsync(...transforms)(data);
1552
+ return pipe(...transforms)(data);
2142
1553
  };
2143
1554
  const sanitizeQuery = async (query, schema, { auth } = {}) => {
2144
1555
  if (!schema) {
@@ -2171,7 +1582,7 @@ const createContentAPISanitizers = () => {
2171
1582
  if (auth) {
2172
1583
  transforms.push(traverseQueryFilters(removeRestrictedRelations(auth), { schema }));
2173
1584
  }
2174
- return pipeAsync(...transforms)(filters2);
1585
+ return pipe(...transforms)(filters2);
2175
1586
  };
2176
1587
  const sanitizeSort = (sort2, schema, { auth } = {}) => {
2177
1588
  if (!schema) {
@@ -2181,14 +1592,14 @@ const createContentAPISanitizers = () => {
2181
1592
  if (auth) {
2182
1593
  transforms.push(traverseQuerySort(removeRestrictedRelations(auth), { schema }));
2183
1594
  }
2184
- return pipeAsync(...transforms)(sort2);
1595
+ return pipe(...transforms)(sort2);
2185
1596
  };
2186
1597
  const sanitizeFields = (fields2, schema) => {
2187
1598
  if (!schema) {
2188
1599
  throw new Error("Missing schema in sanitizeFields");
2189
1600
  }
2190
1601
  const transforms = [defaultSanitizeFields(schema)];
2191
- return pipeAsync(...transforms)(fields2);
1602
+ return pipe(...transforms)(fields2);
2192
1603
  };
2193
1604
  const sanitizePopulate = (populate2, schema, { auth } = {}) => {
2194
1605
  if (!schema) {
@@ -2198,7 +1609,7 @@ const createContentAPISanitizers = () => {
2198
1609
  if (auth) {
2199
1610
  transforms.push(traverseQueryPopulate(removeRestrictedRelations(auth), { schema }));
2200
1611
  }
2201
- return pipeAsync(...transforms)(populate2);
1612
+ return pipe(...transforms)(populate2);
2202
1613
  };
2203
1614
  return {
2204
1615
  input: sanitizeInput,
@@ -2216,26 +1627,134 @@ const index$1 = {
2216
1627
  sanitizers,
2217
1628
  visitors: visitors$1
2218
1629
  };
2219
- const throwInvalidParam = ({ key: key2 }) => {
2220
- throw new ValidationError(`Invalid parameter ${key2}`);
1630
+ const formatYupInnerError = (yupError) => ({
1631
+ path: fp.toPath(yupError.path),
1632
+ message: yupError.message,
1633
+ name: yupError.name
1634
+ });
1635
+ const formatYupErrors = (yupError) => ({
1636
+ errors: fp.isEmpty(yupError.inner) ? [formatYupInnerError(yupError)] : yupError.inner.map(formatYupInnerError),
1637
+ message: yupError.message
1638
+ });
1639
+ class ApplicationError extends Error {
1640
+ name;
1641
+ details;
1642
+ message;
1643
+ constructor(message = "An application error occured", details = {}) {
1644
+ super();
1645
+ this.name = "ApplicationError";
1646
+ this.message = message;
1647
+ this.details = details;
1648
+ }
1649
+ }
1650
+ class ValidationError extends ApplicationError {
1651
+ constructor(message, details) {
1652
+ super(message, details);
1653
+ this.name = "ValidationError";
1654
+ }
1655
+ }
1656
+ class YupValidationError extends ValidationError {
1657
+ constructor(yupError, message) {
1658
+ super("Validation");
1659
+ const { errors: errors2, message: yupMessage } = formatYupErrors(yupError);
1660
+ this.message = message || yupMessage;
1661
+ this.details = { errors: errors2 };
1662
+ }
1663
+ }
1664
+ class PaginationError extends ApplicationError {
1665
+ constructor(message = "Invalid pagination", details) {
1666
+ super(message, details);
1667
+ this.name = "PaginationError";
1668
+ this.message = message;
1669
+ }
1670
+ }
1671
+ class NotFoundError extends ApplicationError {
1672
+ constructor(message = "Entity not found", details) {
1673
+ super(message, details);
1674
+ this.name = "NotFoundError";
1675
+ this.message = message;
1676
+ }
1677
+ }
1678
+ class ForbiddenError extends ApplicationError {
1679
+ constructor(message = "Forbidden access", details) {
1680
+ super(message, details);
1681
+ this.name = "ForbiddenError";
1682
+ this.message = message;
1683
+ }
1684
+ }
1685
+ class UnauthorizedError extends ApplicationError {
1686
+ constructor(message = "Unauthorized", details) {
1687
+ super(message, details);
1688
+ this.name = "UnauthorizedError";
1689
+ this.message = message;
1690
+ }
1691
+ }
1692
+ class RateLimitError extends ApplicationError {
1693
+ constructor(message = "Too many requests, please try again later.", details) {
1694
+ super(message, details);
1695
+ this.name = "RateLimitError";
1696
+ this.message = message;
1697
+ this.details = details || {};
1698
+ }
1699
+ }
1700
+ class PayloadTooLargeError extends ApplicationError {
1701
+ constructor(message = "Entity too large", details) {
1702
+ super(message, details);
1703
+ this.name = "PayloadTooLargeError";
1704
+ this.message = message;
1705
+ }
1706
+ }
1707
+ class PolicyError extends ForbiddenError {
1708
+ constructor(message = "Policy Failed", details) {
1709
+ super(message, details);
1710
+ this.name = "PolicyError";
1711
+ this.message = message;
1712
+ this.details = details || {};
1713
+ }
1714
+ }
1715
+ class NotImplementedError extends ApplicationError {
1716
+ constructor(message = "This feature is not implemented yet", details) {
1717
+ super(message, details);
1718
+ this.name = "NotImplementedError";
1719
+ this.message = message;
1720
+ }
1721
+ }
1722
+ const errors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1723
+ __proto__: null,
1724
+ ApplicationError,
1725
+ ForbiddenError,
1726
+ HttpError: httpErrors.HttpError,
1727
+ NotFoundError,
1728
+ NotImplementedError,
1729
+ PaginationError,
1730
+ PayloadTooLargeError,
1731
+ PolicyError,
1732
+ RateLimitError,
1733
+ UnauthorizedError,
1734
+ ValidationError,
1735
+ YupValidationError
1736
+ }, Symbol.toStringTag, { value: "Module" }));
1737
+ const throwInvalidParam = ({ key, path }) => {
1738
+ const msg = path && path !== key ? `Invalid parameter ${key} at ${path}` : `Invalid parameter ${key}`;
1739
+ throw new ValidationError(msg);
2221
1740
  };
2222
- const visitor$3 = ({ key: key2, attribute }) => {
1741
+ const visitor$3 = ({ key, attribute, path }) => {
2223
1742
  if (attribute?.type === "password") {
2224
- throwInvalidParam({ key: key2 });
1743
+ throwInvalidParam({ key, path: path.attribute });
2225
1744
  }
2226
1745
  };
2227
- const visitor$2 = ({ schema, key: key2, attribute }) => {
1746
+ const visitor$2 = ({ schema, key, attribute, path }) => {
2228
1747
  if (!attribute) {
2229
1748
  return;
2230
1749
  }
2231
- const isPrivate = attribute.private === true || isPrivateAttribute(schema, key2);
1750
+ const isPrivate = attribute.private === true || isPrivateAttribute(schema, key);
2232
1751
  if (isPrivate) {
2233
- throwInvalidParam({ key: key2 });
1752
+ throwInvalidParam({ key, path: path.attribute });
2234
1753
  }
2235
1754
  };
2236
1755
  const ACTIONS_TO_VERIFY = ["find"];
2237
1756
  const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = constants$1;
2238
- const throwRestrictedRelations = (auth) => async ({ data, key: key2, attribute, schema }) => {
1757
+ const throwRestrictedRelations = (auth) => async ({ data, key, attribute, schema, path }) => {
2239
1758
  if (!attribute) {
2240
1759
  return;
2241
1760
  }
@@ -2244,11 +1763,11 @@ const throwRestrictedRelations = (auth) => async ({ data, key: key2, attribute,
2244
1763
  return;
2245
1764
  }
2246
1765
  const handleMorphRelation = async () => {
2247
- for (const element of data[key2]) {
1766
+ for (const element of data[key]) {
2248
1767
  const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);
2249
1768
  const isAllowed = await hasAccessToSomeScopes(scopes, auth);
2250
1769
  if (!isAllowed) {
2251
- throwInvalidParam({ key: key2 });
1770
+ throwInvalidParam({ key, path: path.attribute });
2252
1771
  }
2253
1772
  }
2254
1773
  };
@@ -2256,10 +1775,10 @@ const throwRestrictedRelations = (auth) => async ({ data, key: key2, attribute,
2256
1775
  const scopes = ACTIONS_TO_VERIFY.map((action) => `${attribute.target}.${action}`);
2257
1776
  const isAllowed = await hasAccessToSomeScopes(scopes, auth);
2258
1777
  if (!isAllowed) {
2259
- throwInvalidParam({ key: key2 });
1778
+ throwInvalidParam({ key, path: path.attribute });
2260
1779
  }
2261
1780
  };
2262
- const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key2);
1781
+ const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);
2263
1782
  if (isMorphToRelationalAttribute(attribute)) {
2264
1783
  await handleMorphRelation();
2265
1784
  return;
@@ -2280,17 +1799,17 @@ const hasAccessToSomeScopes = async (scopes, auth) => {
2280
1799
  }
2281
1800
  return false;
2282
1801
  };
2283
- const visitor$1 = ({ key: key2, attribute }) => {
1802
+ const visitor$1 = ({ key, attribute, path }) => {
2284
1803
  if (isMorphToRelationalAttribute(attribute)) {
2285
- throwInvalidParam({ key: key2 });
1804
+ throwInvalidParam({ key, path: path.attribute });
2286
1805
  }
2287
1806
  };
2288
- const visitor = ({ key: key2, attribute }) => {
1807
+ const visitor = ({ key, attribute, path }) => {
2289
1808
  if (isDynamicZoneAttribute(attribute)) {
2290
- throwInvalidParam({ key: key2 });
1809
+ throwInvalidParam({ key, path: path.attribute });
2291
1810
  }
2292
1811
  };
2293
- const throwDisallowedFields = (allowedFields = null) => ({ key: key2, path: { attribute: path } }) => {
1812
+ const throwDisallowedFields = (allowedFields = null) => ({ key, path: { attribute: path } }) => {
2294
1813
  if (allowedFields === null) {
2295
1814
  return;
2296
1815
  }
@@ -2309,17 +1828,17 @@ const throwDisallowedFields = (allowedFields = null) => ({ key: key2, path: { at
2309
1828
  if (isPathAllowed) {
2310
1829
  return;
2311
1830
  }
2312
- throwInvalidParam({ key: key2 });
1831
+ throwInvalidParam({ key, path });
2313
1832
  };
2314
1833
  const getContainedPaths = (path) => {
2315
1834
  const parts = fp.toPath(path);
2316
- return parts.reduce((acc2, value2, index2, list) => {
2317
- return [...acc2, list.slice(0, index2 + 1).join(".")];
1835
+ return parts.reduce((acc, value, index2, list) => {
1836
+ return [...acc, list.slice(0, index2 + 1).join(".")];
2318
1837
  }, []);
2319
1838
  };
2320
- const throwRestrictedFields = (restrictedFields = null) => ({ key: key2, path: { attribute: path } }) => {
1839
+ const throwRestrictedFields = (restrictedFields = null) => ({ key, path: { attribute: path } }) => {
2321
1840
  if (restrictedFields === null) {
2322
- throwInvalidParam({ key: key2 });
1841
+ throwInvalidParam({ key, path });
2323
1842
  }
2324
1843
  if (!(fp.isArray(restrictedFields) && restrictedFields.every(fp.isString))) {
2325
1844
  throw new TypeError(
@@ -2327,13 +1846,13 @@ const throwRestrictedFields = (restrictedFields = null) => ({ key: key2, path: {
2327
1846
  );
2328
1847
  }
2329
1848
  if (restrictedFields.includes(path)) {
2330
- throwInvalidParam({ key: key2 });
1849
+ throwInvalidParam({ key, path });
2331
1850
  }
2332
1851
  const isRestrictedNested = restrictedFields.some(
2333
1852
  (allowedPath) => path?.toString().startsWith(`${allowedPath}.`)
2334
1853
  );
2335
1854
  if (isRestrictedNested) {
2336
- throwInvalidParam({ key: key2 });
1855
+ throwInvalidParam({ key, path });
2337
1856
  }
2338
1857
  };
2339
1858
  const visitors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -2346,6 +1865,7 @@ const visitors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
2346
1865
  throwRestrictedFields,
2347
1866
  throwRestrictedRelations
2348
1867
  }, Symbol.toStringTag, { value: "Module" }));
1868
+ const { ID_ATTRIBUTE: ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE: DOC_ID_ATTRIBUTE$2 } = constants$1;
2349
1869
  const throwPasswords = (schema) => async (entity) => {
2350
1870
  if (!schema) {
2351
1871
  throw new Error("Missing schema in throwPasswords");
@@ -2356,16 +1876,16 @@ const defaultValidateFilters = fp.curry((schema, filters2) => {
2356
1876
  if (!schema) {
2357
1877
  throw new Error("Missing schema in defaultValidateFilters");
2358
1878
  }
2359
- return pipeAsync(
1879
+ return pipe(
2360
1880
  // keys that are not attributes or valid operators
2361
1881
  traverseQueryFilters(
2362
- ({ key: key2, attribute }) => {
2363
- if (key2 === "id") {
1882
+ ({ key, attribute, path }) => {
1883
+ if ([ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE$2].includes(key)) {
2364
1884
  return;
2365
1885
  }
2366
1886
  const isAttribute = !!attribute;
2367
- if (!isAttribute && !isOperator(key2)) {
2368
- throwInvalidParam({ key: key2 });
1887
+ if (!isAttribute && !isOperator(key)) {
1888
+ throwInvalidParam({ key, path: path.attribute });
2369
1889
  }
2370
1890
  },
2371
1891
  { schema }
@@ -2385,15 +1905,15 @@ const defaultValidateSort = fp.curry((schema, sort2) => {
2385
1905
  if (!schema) {
2386
1906
  throw new Error("Missing schema in defaultValidateSort");
2387
1907
  }
2388
- return pipeAsync(
1908
+ return pipe(
2389
1909
  // non attribute keys
2390
1910
  traverseQuerySort(
2391
- ({ key: key2, attribute }) => {
2392
- if (key2 === "id") {
1911
+ ({ key, attribute, path }) => {
1912
+ if ([ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE$2].includes(key)) {
2393
1913
  return;
2394
1914
  }
2395
1915
  if (!attribute) {
2396
- throwInvalidParam({ key: key2 });
1916
+ throwInvalidParam({ key, path: path.attribute });
2397
1917
  }
2398
1918
  },
2399
1919
  { schema }
@@ -2408,12 +1928,12 @@ const defaultValidateSort = fp.curry((schema, sort2) => {
2408
1928
  traverseQuerySort(visitor$3, { schema }),
2409
1929
  // keys for empty non-scalar values
2410
1930
  traverseQuerySort(
2411
- ({ key: key2, attribute, value: value2 }) => {
2412
- if (key2 === "id") {
1931
+ ({ key, attribute, value, path }) => {
1932
+ if ([ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE$2].includes(key)) {
2413
1933
  return;
2414
1934
  }
2415
- if (!isScalarAttribute(attribute) && fp.isEmpty(value2)) {
2416
- throwInvalidParam({ key: key2 });
1935
+ if (!isScalarAttribute(attribute) && fp.isEmpty(value)) {
1936
+ throwInvalidParam({ key, path: path.attribute });
2417
1937
  }
2418
1938
  },
2419
1939
  { schema }
@@ -2424,15 +1944,15 @@ const defaultValidateFields = fp.curry((schema, fields2) => {
2424
1944
  if (!schema) {
2425
1945
  throw new Error("Missing schema in defaultValidateFields");
2426
1946
  }
2427
- return pipeAsync(
1947
+ return pipe(
2428
1948
  // Only allow scalar attributes
2429
1949
  traverseQueryFields(
2430
- ({ key: key2, attribute }) => {
2431
- if (key2 === "id") {
1950
+ ({ key, attribute, path }) => {
1951
+ if ([ID_ATTRIBUTE$2, DOC_ID_ATTRIBUTE$2].includes(key)) {
2432
1952
  return;
2433
1953
  }
2434
1954
  if (fp.isNil(attribute) || !isScalarAttribute(attribute)) {
2435
- throwInvalidParam({ key: key2 });
1955
+ throwInvalidParam({ key, path: path.attribute });
2436
1956
  }
2437
1957
  },
2438
1958
  { schema }
@@ -2443,13 +1963,44 @@ const defaultValidateFields = fp.curry((schema, fields2) => {
2443
1963
  traverseQueryFields(visitor$3, { schema })
2444
1964
  )(fields2);
2445
1965
  });
1966
+ const defaultValidatePopulate = fp.curry((schema, populate2) => {
1967
+ if (!schema) {
1968
+ throw new Error("Missing schema in defaultValidatePopulate");
1969
+ }
1970
+ return pipe(
1971
+ traverseQueryPopulate(
1972
+ async ({ key, value, schema: schema2, attribute }, { set }) => {
1973
+ if (attribute) {
1974
+ return;
1975
+ }
1976
+ if (key === "sort") {
1977
+ set(key, await defaultValidateSort(schema2, value));
1978
+ }
1979
+ if (key === "filters") {
1980
+ set(key, await defaultValidateFilters(schema2, value));
1981
+ }
1982
+ if (key === "fields") {
1983
+ set(key, await defaultValidateFields(schema2, value));
1984
+ }
1985
+ if (key === "populate") {
1986
+ set(key, await defaultValidatePopulate(schema2, value));
1987
+ }
1988
+ },
1989
+ { schema }
1990
+ ),
1991
+ // Remove private fields
1992
+ traverseQueryPopulate(visitor$2, { schema })
1993
+ )(populate2);
1994
+ });
2446
1995
  const validators = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2447
1996
  __proto__: null,
2448
1997
  defaultValidateFields,
2449
1998
  defaultValidateFilters,
1999
+ defaultValidatePopulate,
2450
2000
  defaultValidateSort,
2451
2001
  throwPasswords
2452
2002
  }, Symbol.toStringTag, { value: "Module" }));
2003
+ const { ID_ATTRIBUTE: ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE: DOC_ID_ATTRIBUTE$1 } = constants$1;
2453
2004
  const createContentAPIValidators = () => {
2454
2005
  const validateInput = async (data, schema, { auth } = {}) => {
2455
2006
  if (!schema) {
@@ -2462,8 +2013,13 @@ const createContentAPIValidators = () => {
2462
2013
  const nonWritableAttributes = getNonWritableAttributes(schema);
2463
2014
  const transforms = [
2464
2015
  (data2) => {
2465
- if (fp.isObject(data2) && "id" in data2) {
2466
- throwInvalidParam({ key: "id" });
2016
+ if (fp.isObject(data2)) {
2017
+ if (ID_ATTRIBUTE$1 in data2) {
2018
+ throwInvalidParam({ key: ID_ATTRIBUTE$1 });
2019
+ }
2020
+ if (DOC_ID_ATTRIBUTE$1 in data2) {
2021
+ throwInvalidParam({ key: DOC_ID_ATTRIBUTE$1 });
2022
+ }
2467
2023
  }
2468
2024
  },
2469
2025
  // non-writable attributes
@@ -2473,13 +2029,13 @@ const createContentAPIValidators = () => {
2473
2029
  transforms.push(traverseEntity$1(throwRestrictedRelations(auth), { schema }));
2474
2030
  }
2475
2031
  strapi.validators.get("content-api.input").forEach((validator) => transforms.push(validator(schema)));
2476
- pipeAsync(...transforms)(data);
2032
+ await pipe(...transforms)(data);
2477
2033
  };
2478
2034
  const validateQuery = async (query, schema, { auth } = {}) => {
2479
2035
  if (!schema) {
2480
2036
  throw new Error("Missing schema in validateQuery");
2481
2037
  }
2482
- const { filters: filters2, sort: sort2, fields: fields2 } = query;
2038
+ const { filters: filters2, sort: sort2, fields: fields2, populate: populate2 } = query;
2483
2039
  if (filters2) {
2484
2040
  await validateFilters(filters2, schema, { auth });
2485
2041
  }
@@ -2489,6 +2045,9 @@ const createContentAPIValidators = () => {
2489
2045
  if (fields2) {
2490
2046
  await validateFields(fields2, schema);
2491
2047
  }
2048
+ if (populate2 && populate2 !== "*") {
2049
+ await validatePopulate(populate2, schema);
2050
+ }
2492
2051
  };
2493
2052
  const validateFilters = async (filters2, schema, { auth } = {}) => {
2494
2053
  if (!schema) {
@@ -2502,7 +2061,7 @@ const createContentAPIValidators = () => {
2502
2061
  if (auth) {
2503
2062
  transforms.push(traverseQueryFilters(throwRestrictedRelations(auth), { schema }));
2504
2063
  }
2505
- return pipeAsync(...transforms)(filters2);
2064
+ await pipe(...transforms)(filters2);
2506
2065
  };
2507
2066
  const validateSort = async (sort2, schema, { auth } = {}) => {
2508
2067
  if (!schema) {
@@ -2512,21 +2071,32 @@ const createContentAPIValidators = () => {
2512
2071
  if (auth) {
2513
2072
  transforms.push(traverseQuerySort(throwRestrictedRelations(auth), { schema }));
2514
2073
  }
2515
- return pipeAsync(...transforms)(sort2);
2074
+ await pipe(...transforms)(sort2);
2516
2075
  };
2517
- const validateFields = (fields2, schema) => {
2076
+ const validateFields = async (fields2, schema) => {
2518
2077
  if (!schema) {
2519
2078
  throw new Error("Missing schema in validateFields");
2520
2079
  }
2521
2080
  const transforms = [defaultValidateFields(schema)];
2522
- return pipeAsync(...transforms)(fields2);
2081
+ await pipe(...transforms)(fields2);
2082
+ };
2083
+ const validatePopulate = async (populate2, schema, { auth } = {}) => {
2084
+ if (!schema) {
2085
+ throw new Error("Missing schema in sanitizePopulate");
2086
+ }
2087
+ const transforms = [defaultValidatePopulate(schema)];
2088
+ if (auth) {
2089
+ transforms.push(traverseQueryPopulate(throwRestrictedRelations(auth), { schema }));
2090
+ }
2091
+ await pipe(...transforms)(populate2);
2523
2092
  };
2524
2093
  return {
2525
2094
  input: validateInput,
2526
2095
  query: validateQuery,
2527
2096
  filters: validateFilters,
2528
2097
  sort: validateSort,
2529
- fields: validateFields
2098
+ fields: validateFields,
2099
+ populate: validatePopulate
2530
2100
  };
2531
2101
  };
2532
2102
  const contentAPI = createContentAPIValidators();
@@ -2535,7 +2105,7 @@ const index = {
2535
2105
  validators,
2536
2106
  visitors
2537
2107
  };
2538
- const { PUBLISHED_AT_ATTRIBUTE } = constants$1;
2108
+ const { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, PUBLISHED_AT_ATTRIBUTE } = constants$1;
2539
2109
  class InvalidOrderError extends Error {
2540
2110
  constructor() {
2541
2111
  super();
@@ -2559,8 +2129,8 @@ const convertCountQueryParams = (countQuery) => {
2559
2129
  const convertOrderingQueryParams = (ordering) => {
2560
2130
  return ordering;
2561
2131
  };
2562
- const isPlainObject = (value2) => ___default.default.isPlainObject(value2);
2563
- const isStringArray = (value2) => fp.isArray(value2) && value2.every(fp.isString);
2132
+ const isPlainObject = (value) => ___default.default.isPlainObject(value);
2133
+ const isStringArray = (value) => fp.isArray(value) && value.every(fp.isString);
2564
2134
  const convertSortQueryParams = (sortQuery) => {
2565
2135
  if (typeof sortQuery === "string") {
2566
2136
  return convertStringSortQueryParam(sortQuery);
@@ -2577,7 +2147,7 @@ const convertSortQueryParams = (sortQuery) => {
2577
2147
  throw new InvalidSortError();
2578
2148
  };
2579
2149
  const convertStringSortQueryParam = (sortQuery) => {
2580
- return sortQuery.split(",").map((value2) => convertSingleSortQueryParam(value2));
2150
+ return sortQuery.split(",").map((value) => convertSingleSortQueryParam(value));
2581
2151
  };
2582
2152
  const convertSingleSortQueryParam = (sortQuery) => {
2583
2153
  if (!sortQuery) {
@@ -2663,15 +2233,15 @@ const convertPopulateQueryParams = (populate2, schema, depth = 0) => {
2663
2233
  return true;
2664
2234
  }
2665
2235
  if (typeof populate2 === "string") {
2666
- return populate2.split(",").map((value2) => ___default.default.trim(value2));
2236
+ return populate2.split(",").map((value) => ___default.default.trim(value));
2667
2237
  }
2668
2238
  if (Array.isArray(populate2)) {
2669
2239
  return ___default.default.uniq(
2670
- populate2.flatMap((value2) => {
2671
- if (typeof value2 !== "string") {
2240
+ populate2.flatMap((value) => {
2241
+ if (typeof value !== "string") {
2672
2242
  throw new InvalidPopulateError();
2673
2243
  }
2674
- return value2.split(",").map((value22) => ___default.default.trim(value22));
2244
+ return value.split(",").map((value2) => ___default.default.trim(value2));
2675
2245
  })
2676
2246
  );
2677
2247
  }
@@ -2680,25 +2250,30 @@ const convertPopulateQueryParams = (populate2, schema, depth = 0) => {
2680
2250
  }
2681
2251
  throw new InvalidPopulateError();
2682
2252
  };
2253
+ const hasFragmentPopulateDefined = (populate2) => {
2254
+ return typeof populate2 === "object" && "on" in populate2 && !fp.isNil(populate2.on);
2255
+ };
2683
2256
  const convertPopulateObject = (populate2, schema) => {
2684
2257
  if (!schema) {
2685
2258
  return {};
2686
2259
  }
2687
2260
  const { attributes } = schema;
2688
- return Object.entries(populate2).reduce((acc2, [key2, subPopulate]) => {
2689
- const attribute = attributes[key2];
2261
+ return Object.entries(populate2).reduce((acc, [key, subPopulate]) => {
2262
+ if (___default.default.isBoolean(subPopulate)) {
2263
+ return { ...acc, [key]: subPopulate };
2264
+ }
2265
+ const attribute = attributes[key];
2690
2266
  if (!attribute) {
2691
- return acc2;
2267
+ return acc;
2692
2268
  }
2693
2269
  const isAllowedAttributeForFragmentPopulate = isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);
2694
- const hasFragmentPopulateDefined = typeof subPopulate === "object" && "on" in subPopulate && !fp.isNil(subPopulate.on);
2695
- if (isAllowedAttributeForFragmentPopulate && hasFragmentPopulateDefined) {
2270
+ if (isAllowedAttributeForFragmentPopulate && hasFragmentPopulateDefined(subPopulate)) {
2696
2271
  return {
2697
- ...acc2,
2698
- [key2]: {
2272
+ ...acc,
2273
+ [key]: {
2699
2274
  on: Object.entries(subPopulate.on).reduce(
2700
- (acc22, [type, typeSubPopulate]) => ({
2701
- ...acc22,
2275
+ (acc2, [type, typeSubPopulate]) => ({
2276
+ ...acc2,
2702
2277
  [type]: convertNestedPopulate(typeSubPopulate, strapi.getModel(type))
2703
2278
  }),
2704
2279
  {}
@@ -2709,15 +2284,15 @@ const convertPopulateObject = (populate2, schema) => {
2709
2284
  if (isDynamicZoneAttribute(attribute)) {
2710
2285
  const populates = attribute.components.map((uid) => strapi.getModel(uid)).map((schema2) => convertNestedPopulate(subPopulate, schema2)).map((populate22) => populate22 === true ? {} : populate22).filter((populate22) => populate22 !== false);
2711
2286
  if (fp.isEmpty(populates)) {
2712
- return acc2;
2287
+ return acc;
2713
2288
  }
2714
2289
  return {
2715
- ...acc2,
2716
- [key2]: fp.mergeAll(populates)
2290
+ ...acc,
2291
+ [key]: fp.mergeAll(populates)
2717
2292
  };
2718
2293
  }
2719
2294
  if (isMorphToRelationalAttribute(attribute)) {
2720
- return { ...acc2, [key2]: convertNestedPopulate(subPopulate, void 0) };
2295
+ return { ...acc, [key]: convertNestedPopulate(subPopulate, void 0) };
2721
2296
  }
2722
2297
  let targetSchemaUID;
2723
2298
  if (attribute.type === "relation") {
@@ -2727,19 +2302,19 @@ const convertPopulateObject = (populate2, schema) => {
2727
2302
  } else if (attribute.type === "media") {
2728
2303
  targetSchemaUID = "plugin::upload.file";
2729
2304
  } else {
2730
- return acc2;
2305
+ return acc;
2731
2306
  }
2732
2307
  const targetSchema = strapi.getModel(targetSchemaUID);
2733
2308
  if (!targetSchema) {
2734
- return acc2;
2309
+ return acc;
2735
2310
  }
2736
2311
  const populateObject = convertNestedPopulate(subPopulate, targetSchema);
2737
2312
  if (!populateObject) {
2738
- return acc2;
2313
+ return acc;
2739
2314
  }
2740
2315
  return {
2741
- ...acc2,
2742
- [key2]: populateObject
2316
+ ...acc,
2317
+ [key]: populateObject
2743
2318
  };
2744
2319
  }, {});
2745
2320
  };
@@ -2773,280 +2348,705 @@ const convertNestedPopulate = (subPopulate, schema) => {
2773
2348
  if (ordering) {
2774
2349
  query.ordering = convertOrderingQueryParams(ordering);
2775
2350
  }
2776
- validatePaginationParams(page, pageSize, start, limit);
2777
- if (!fp.isNil(page)) {
2778
- query.page = convertPageQueryParams(page);
2351
+ validatePaginationParams(page, pageSize, start, limit);
2352
+ if (!fp.isNil(page)) {
2353
+ query.page = convertPageQueryParams(page);
2354
+ }
2355
+ if (!fp.isNil(pageSize)) {
2356
+ query.pageSize = convertPageSizeQueryParams(pageSize, page);
2357
+ }
2358
+ if (!fp.isNil(start)) {
2359
+ query.offset = convertStartQueryParams(start);
2360
+ }
2361
+ if (!fp.isNil(limit)) {
2362
+ query.limit = convertLimitQueryParams(limit);
2363
+ }
2364
+ return query;
2365
+ };
2366
+ const convertFieldsQueryParams = (fields2, depth = 0) => {
2367
+ if (depth === 0 && fields2 === "*") {
2368
+ return void 0;
2369
+ }
2370
+ if (typeof fields2 === "string") {
2371
+ const fieldsValues = fields2.split(",").map((value) => ___default.default.trim(value));
2372
+ return ___default.default.uniq([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, ...fieldsValues]);
2373
+ }
2374
+ if (isStringArray(fields2)) {
2375
+ const fieldsValues = fields2.flatMap((value) => convertFieldsQueryParams(value, depth + 1)).filter((v) => !fp.isNil(v));
2376
+ return ___default.default.uniq([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, ...fieldsValues]);
2377
+ }
2378
+ throw new Error("Invalid fields parameter. Expected a string or an array of strings");
2379
+ };
2380
+ const isValidSchemaAttribute = (key, schema) => {
2381
+ if ([DOC_ID_ATTRIBUTE, ID_ATTRIBUTE].includes(key)) {
2382
+ return true;
2383
+ }
2384
+ if (!schema) {
2385
+ return false;
2386
+ }
2387
+ return Object.keys(schema.attributes).includes(key);
2388
+ };
2389
+ const convertFiltersQueryParams = (filters2, schema) => {
2390
+ if (!fp.isObject(filters2)) {
2391
+ throw new Error("The filters parameter must be an object or an array");
2392
+ }
2393
+ const filtersCopy = fp.cloneDeep(filters2);
2394
+ return convertAndSanitizeFilters(filtersCopy, schema);
2395
+ };
2396
+ const convertAndSanitizeFilters = (filters2, schema) => {
2397
+ if (Array.isArray(filters2)) {
2398
+ return filters2.map((filter) => convertAndSanitizeFilters(filter, schema)).filter((filter) => !isPlainObject(filter) || !fp.isEmpty(filter));
2399
+ }
2400
+ if (!isPlainObject(filters2)) {
2401
+ return filters2;
2402
+ }
2403
+ const removeOperator = (operator) => delete filters2[operator];
2404
+ for (const [key, value] of Object.entries(filters2)) {
2405
+ const attribute = fp.get(key, schema?.attributes);
2406
+ const validKey = isOperator(key) || isValidSchemaAttribute(key, schema);
2407
+ if (!validKey) {
2408
+ removeOperator(key);
2409
+ } else if (attribute) {
2410
+ if (attribute.type === "relation") {
2411
+ filters2[key] = convertAndSanitizeFilters(value, strapi.getModel(attribute.target));
2412
+ } else if (attribute.type === "component") {
2413
+ filters2[key] = convertAndSanitizeFilters(value, strapi.getModel(attribute.component));
2414
+ } else if (attribute.type === "media") {
2415
+ filters2[key] = convertAndSanitizeFilters(value, strapi.getModel("plugin::upload.file"));
2416
+ } else if (attribute.type === "dynamiczone") {
2417
+ removeOperator(key);
2418
+ } else if (attribute.type === "password") {
2419
+ removeOperator(key);
2420
+ } else {
2421
+ filters2[key] = convertAndSanitizeFilters(value, schema);
2422
+ }
2423
+ } else if (["$null", "$notNull"].includes(key)) {
2424
+ filters2[key] = parseType({ type: "boolean", value: filters2[key], forceCast: true });
2425
+ } else if (fp.isObject(value)) {
2426
+ filters2[key] = convertAndSanitizeFilters(value, schema);
2427
+ }
2428
+ if (isPlainObject(filters2[key]) && fp.isEmpty(filters2[key])) {
2429
+ removeOperator(key);
2430
+ }
2431
+ }
2432
+ return filters2;
2433
+ };
2434
+ const convertStatusParams = (status, query = {}) => {
2435
+ query.filters = ({ meta }) => {
2436
+ const contentType = strapi.contentTypes[meta.uid];
2437
+ if (!contentType || !hasDraftAndPublish(contentType)) {
2438
+ return {};
2439
+ }
2440
+ return { [PUBLISHED_AT_ATTRIBUTE]: { $null: status === "draft" } };
2441
+ };
2442
+ };
2443
+ const transformParamsToQuery = (uid, params) => {
2444
+ const schema = strapi.getModel(uid);
2445
+ const query = {};
2446
+ const { _q, sort: sort2, filters: filters2, fields: fields2, populate: populate2, page, pageSize, start, limit, status, ...rest } = params;
2447
+ if (!fp.isNil(status)) {
2448
+ convertStatusParams(status, query);
2449
+ }
2450
+ if (!fp.isNil(_q)) {
2451
+ query._q = _q;
2452
+ }
2453
+ if (!fp.isNil(sort2)) {
2454
+ query.orderBy = convertSortQueryParams(sort2);
2455
+ }
2456
+ if (!fp.isNil(filters2)) {
2457
+ query.where = convertFiltersQueryParams(filters2, schema);
2458
+ }
2459
+ if (!fp.isNil(fields2)) {
2460
+ query.select = convertFieldsQueryParams(fields2);
2461
+ }
2462
+ if (!fp.isNil(populate2)) {
2463
+ query.populate = convertPopulateQueryParams(populate2, schema);
2464
+ }
2465
+ validatePaginationParams(page, pageSize, start, limit);
2466
+ if (!fp.isNil(page)) {
2467
+ query.page = convertPageQueryParams(page);
2468
+ }
2469
+ if (!fp.isNil(pageSize)) {
2470
+ query.pageSize = convertPageSizeQueryParams(pageSize, page);
2471
+ }
2472
+ if (!fp.isNil(start)) {
2473
+ query.offset = convertStartQueryParams(start);
2474
+ }
2475
+ if (!fp.isNil(limit)) {
2476
+ query.limit = convertLimitQueryParams(limit);
2477
+ }
2478
+ return {
2479
+ ...rest,
2480
+ ...query
2481
+ };
2482
+ };
2483
+ const convertQueryParams = {
2484
+ convertSortQueryParams,
2485
+ convertStartQueryParams,
2486
+ convertLimitQueryParams,
2487
+ convertPopulateQueryParams,
2488
+ convertFiltersQueryParams,
2489
+ convertFieldsQueryParams,
2490
+ transformParamsToQuery
2491
+ };
2492
+ function importDefault(modName) {
2493
+ const mod = require(modName);
2494
+ return mod && mod.__esModule ? mod.default : mod;
2495
+ }
2496
+ const machineId = () => {
2497
+ try {
2498
+ const deviceId = nodeMachineId.machineIdSync();
2499
+ return deviceId;
2500
+ } catch (error) {
2501
+ const deviceId = crypto.randomUUID();
2502
+ return deviceId;
2503
+ }
2504
+ };
2505
+ const handleYupError = (error, errorMessage) => {
2506
+ throw new YupValidationError(error, errorMessage);
2507
+ };
2508
+ const defaultValidationParam = { strict: true, abortEarly: false };
2509
+ const validateYupSchema = (schema, options = {}) => async (body, errorMessage) => {
2510
+ try {
2511
+ const optionsWithDefaults = fp.defaults(defaultValidationParam, options);
2512
+ const result = await schema.validate(body, optionsWithDefaults);
2513
+ return result;
2514
+ } catch (e) {
2515
+ if (e instanceof yup__namespace.ValidationError) {
2516
+ handleYupError(e, errorMessage);
2517
+ }
2518
+ throw e;
2519
+ }
2520
+ };
2521
+ const validateYupSchemaSync = (schema, options = {}) => (body, errorMessage) => {
2522
+ try {
2523
+ const optionsWithDefaults = fp.defaults(defaultValidationParam, options);
2524
+ return schema.validateSync(body, optionsWithDefaults);
2525
+ } catch (e) {
2526
+ if (e instanceof yup__namespace.ValidationError) {
2527
+ handleYupError(e, errorMessage);
2528
+ }
2529
+ throw e;
2530
+ }
2531
+ };
2532
+ const STRAPI_DEFAULTS = {
2533
+ offset: {
2534
+ start: 0,
2535
+ limit: 10
2536
+ },
2537
+ page: {
2538
+ page: 1,
2539
+ pageSize: 10
2540
+ }
2541
+ };
2542
+ const paginationAttributes = ["start", "limit", "page", "pageSize"];
2543
+ const withMaxLimit = (limit, maxLimit = -1) => {
2544
+ if (maxLimit === -1 || limit < maxLimit) {
2545
+ return limit;
2546
+ }
2547
+ return maxLimit;
2548
+ };
2549
+ const ensureMinValues = ({ start, limit }) => ({
2550
+ start: Math.max(start, 0),
2551
+ limit: limit === -1 ? limit : Math.max(limit, 1)
2552
+ });
2553
+ const ensureMaxValues = (maxLimit = -1) => ({ start, limit }) => ({
2554
+ start,
2555
+ limit: withMaxLimit(limit, maxLimit)
2556
+ });
2557
+ const withNoLimit = (pagination2, maxLimit = -1) => ({
2558
+ ...pagination2,
2559
+ limit: pagination2.limit === -1 ? maxLimit : pagination2.limit
2560
+ });
2561
+ const withDefaultPagination = (args, { defaults = {}, maxLimit = -1 } = {}) => {
2562
+ const defaultValues = fp.merge(STRAPI_DEFAULTS, defaults);
2563
+ const usePagePagination = !fp.isNil(args.page) || !fp.isNil(args.pageSize);
2564
+ const useOffsetPagination = !fp.isNil(args.start) || !fp.isNil(args.limit);
2565
+ const ensureValidValues = fp.pipe(ensureMinValues, ensureMaxValues(maxLimit));
2566
+ if (!usePagePagination && !useOffsetPagination) {
2567
+ return fp.merge(args, ensureValidValues(defaultValues.offset));
2568
+ }
2569
+ if (usePagePagination && useOffsetPagination) {
2570
+ throw new PaginationError("Cannot use both page & offset pagination in the same query");
2779
2571
  }
2780
- if (!fp.isNil(pageSize)) {
2781
- query.pageSize = convertPageSizeQueryParams(pageSize, page);
2572
+ const pagination2 = {
2573
+ start: 0,
2574
+ limit: 0
2575
+ };
2576
+ if (useOffsetPagination) {
2577
+ const { start, limit } = fp.merge(defaultValues.offset, args);
2578
+ Object.assign(pagination2, { start, limit });
2782
2579
  }
2783
- if (!fp.isNil(start)) {
2784
- query.offset = convertStartQueryParams(start);
2580
+ if (usePagePagination) {
2581
+ const { page, pageSize } = fp.merge(defaultValues.page, {
2582
+ ...args,
2583
+ pageSize: Math.max(1, args.pageSize ?? 0)
2584
+ });
2585
+ Object.assign(pagination2, {
2586
+ start: (page - 1) * pageSize,
2587
+ limit: pageSize
2588
+ });
2785
2589
  }
2786
- if (!fp.isNil(limit)) {
2787
- query.limit = convertLimitQueryParams(limit);
2590
+ Object.assign(pagination2, withNoLimit(pagination2, maxLimit));
2591
+ const replacePaginationAttributes = fp.pipe(
2592
+ // Remove pagination attributes
2593
+ fp.omit(paginationAttributes),
2594
+ // Merge the object with the new pagination + ensure minimum & maximum values
2595
+ fp.merge(ensureValidValues(pagination2))
2596
+ );
2597
+ return replacePaginationAttributes(args);
2598
+ };
2599
+ const pagination = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2600
+ __proto__: null,
2601
+ withDefaultPagination
2602
+ }, Symbol.toStringTag, { value: "Module" }));
2603
+ const SUPPORTED_PACKAGE_MANAGERS = ["npm", "yarn"];
2604
+ const DEFAULT_PACKAGE_MANAGER = "npm";
2605
+ const getPreferred = async (pkgPath) => {
2606
+ const pm = await preferredPM__default.default(pkgPath);
2607
+ const hasPackageManager = pm !== void 0;
2608
+ if (!hasPackageManager) {
2609
+ throw new Error(`Couldn't find a package manager in your project.`);
2610
+ }
2611
+ const isPackageManagerSupported = SUPPORTED_PACKAGE_MANAGERS.includes(pm.name);
2612
+ if (!isPackageManagerSupported) {
2613
+ process.emitWarning(
2614
+ `We detected your package manager (${pm.name} v${pm.version}), but it's not officially supported by Strapi yet. Defaulting to npm instead.`
2615
+ );
2616
+ return DEFAULT_PACKAGE_MANAGER;
2788
2617
  }
2789
- convertPublicationStateParams(schema, subPopulate, query);
2790
- return query;
2618
+ return pm.name;
2791
2619
  };
2792
- const convertFieldsQueryParams = (fields2, depth = 0) => {
2793
- if (depth === 0 && fields2 === "*") {
2794
- return void 0;
2620
+ const installDependencies = (path, packageManager2, options = {}) => {
2621
+ return execa__default.default(packageManager2, ["install"], { ...options, cwd: path, stdin: "ignore" });
2622
+ };
2623
+ const packageManager = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2624
+ __proto__: null,
2625
+ getPreferred,
2626
+ installDependencies
2627
+ }, Symbol.toStringTag, { value: "Module" }));
2628
+ const createStrictInterpolationRegExp = (allowedVariableNames, flags) => {
2629
+ const oneOfVariables = allowedVariableNames.join("|");
2630
+ return new RegExp(`<%=\\s*(${oneOfVariables})\\s*%>`, flags);
2631
+ };
2632
+ const createLooseInterpolationRegExp = (flags) => new RegExp(/<%=([\s\S]+?)%>/, flags);
2633
+ const template = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2634
+ __proto__: null,
2635
+ createLooseInterpolationRegExp,
2636
+ createStrictInterpolationRegExp
2637
+ }, Symbol.toStringTag, { value: "Module" }));
2638
+ const kbytesToBytes = (kbytes) => kbytes * 1e3;
2639
+ const bytesToKbytes = (bytes) => Math.round(bytes / 1e3 * 100) / 100;
2640
+ const bytesToHumanReadable = (bytes) => {
2641
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
2642
+ if (bytes === 0)
2643
+ return "0 Bytes";
2644
+ const i = parseInt(`${Math.floor(Math.log(bytes) / Math.log(1e3))}`, 10);
2645
+ return `${Math.round(bytes / 1e3 ** i)} ${sizes[i]}`;
2646
+ };
2647
+ const streamToBuffer = (stream) => new Promise((resolve, reject) => {
2648
+ const chunks = [];
2649
+ stream.on("data", (chunk) => {
2650
+ chunks.push(chunk);
2651
+ });
2652
+ stream.on("end", () => {
2653
+ resolve(Buffer.concat(chunks));
2654
+ });
2655
+ stream.on("error", reject);
2656
+ });
2657
+ const getStreamSize = (stream) => new Promise((resolve, reject) => {
2658
+ let size = 0;
2659
+ stream.on("data", (chunk) => {
2660
+ size += Buffer.byteLength(chunk);
2661
+ });
2662
+ stream.on("close", () => resolve(size));
2663
+ stream.on("error", reject);
2664
+ stream.resume();
2665
+ });
2666
+ function writableDiscardStream(options) {
2667
+ return new node_stream.Writable({
2668
+ ...options,
2669
+ write(chunk, encding, callback) {
2670
+ setImmediate(callback);
2671
+ }
2672
+ });
2673
+ }
2674
+ const file = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2675
+ __proto__: null,
2676
+ bytesToHumanReadable,
2677
+ bytesToKbytes,
2678
+ getStreamSize,
2679
+ kbytesToBytes,
2680
+ streamToBuffer,
2681
+ writableDiscardStream
2682
+ }, Symbol.toStringTag, { value: "Module" }));
2683
+ const PLUGIN_PREFIX = "plugin::";
2684
+ const API_PREFIX = "api::";
2685
+ const parsePolicy = (policy2) => {
2686
+ if (typeof policy2 === "string") {
2687
+ return { policyName: policy2, config: {} };
2795
2688
  }
2796
- if (typeof fields2 === "string") {
2797
- const fieldsValues = fields2.split(",").map((value2) => ___default.default.trim(value2));
2798
- return ___default.default.uniq(["id", ...fieldsValues]);
2689
+ const { name, config } = policy2;
2690
+ return { policyName: name, config };
2691
+ };
2692
+ const searchLocalPolicy = (policyName, policyContext) => {
2693
+ const { pluginName, apiName } = policyContext ?? {};
2694
+ if (pluginName) {
2695
+ return strapi.policy(`${PLUGIN_PREFIX}${pluginName}.${policyName}`);
2799
2696
  }
2800
- if (isStringArray(fields2)) {
2801
- const fieldsValues = fields2.flatMap((value2) => convertFieldsQueryParams(value2, depth + 1)).filter((v) => !fp.isNil(v));
2802
- return ___default.default.uniq(["id", ...fieldsValues]);
2697
+ if (apiName) {
2698
+ return strapi.policy(`${API_PREFIX}${apiName}.${policyName}`);
2803
2699
  }
2804
- throw new Error("Invalid fields parameter. Expected a string or an array of strings");
2805
2700
  };
2806
- const isValidSchemaAttribute = (key2, schema) => {
2807
- if (key2 === "id") {
2808
- return true;
2701
+ const globalPolicy = ({ method, endpoint, controller, action, plugin }) => {
2702
+ return async (ctx, next) => {
2703
+ ctx.request.route = {
2704
+ endpoint: `${method} ${endpoint}`,
2705
+ controller: ___default.default.toLower(controller),
2706
+ action: ___default.default.toLower(action),
2707
+ verb: ___default.default.toLower(method),
2708
+ plugin
2709
+ };
2710
+ await next();
2711
+ };
2712
+ };
2713
+ const resolvePolicies = (config, policyContext) => {
2714
+ const { pluginName, apiName } = policyContext ?? {};
2715
+ return config.map((policyConfig) => {
2716
+ return {
2717
+ handler: getPolicy(policyConfig, { pluginName, apiName }),
2718
+ config: typeof policyConfig === "object" && policyConfig.config || {}
2719
+ };
2720
+ });
2721
+ };
2722
+ const findPolicy = (name, policyContext) => {
2723
+ const { pluginName, apiName } = policyContext ?? {};
2724
+ const resolvedPolicy = strapi.policy(name);
2725
+ if (resolvedPolicy !== void 0) {
2726
+ return resolvedPolicy;
2809
2727
  }
2810
- if (!schema) {
2811
- return false;
2728
+ const localPolicy = searchLocalPolicy(name, { pluginName, apiName });
2729
+ if (localPolicy !== void 0) {
2730
+ return localPolicy;
2812
2731
  }
2813
- return Object.keys(schema.attributes).includes(key2);
2732
+ throw new Error(`Could not find policy "${name}"`);
2814
2733
  };
2815
- const convertFiltersQueryParams = (filters2, schema) => {
2816
- if (!fp.isObject(filters2)) {
2817
- throw new Error("The filters parameter must be an object or an array");
2734
+ const getPolicy = (policyConfig, policyContext) => {
2735
+ const { pluginName, apiName } = policyContext ?? {};
2736
+ if (typeof policyConfig === "function") {
2737
+ return policyConfig;
2818
2738
  }
2819
- const filtersCopy = fp.cloneDeep(filters2);
2820
- return convertAndSanitizeFilters(filtersCopy, schema);
2821
- };
2822
- const convertAndSanitizeFilters = (filters2, schema) => {
2823
- if (Array.isArray(filters2)) {
2824
- return filters2.map((filter) => convertAndSanitizeFilters(filter, schema)).filter((filter) => !isPlainObject(filter) || !fp.isEmpty(filter));
2739
+ const { policyName, config } = parsePolicy(policyConfig);
2740
+ const policy2 = findPolicy(policyName, { pluginName, apiName });
2741
+ if (typeof policy2 === "function") {
2742
+ return policy2;
2825
2743
  }
2826
- if (!isPlainObject(filters2)) {
2827
- return filters2;
2744
+ if (policy2.validator) {
2745
+ policy2.validator(config);
2828
2746
  }
2829
- const removeOperator = (operator) => delete filters2[operator];
2830
- for (const [key2, value2] of Object.entries(filters2)) {
2831
- const attribute = fp.get(key2, schema?.attributes);
2832
- const validKey = isOperator(key2) || isValidSchemaAttribute(key2, schema);
2833
- if (!validKey) {
2834
- removeOperator(key2);
2835
- } else if (attribute) {
2836
- if (attribute.type === "relation") {
2837
- filters2[key2] = convertAndSanitizeFilters(value2, strapi.getModel(attribute.target));
2838
- } else if (attribute.type === "component") {
2839
- filters2[key2] = convertAndSanitizeFilters(value2, strapi.getModel(attribute.component));
2840
- } else if (attribute.type === "media") {
2841
- filters2[key2] = convertAndSanitizeFilters(value2, strapi.getModel("plugin::upload.file"));
2842
- } else if (attribute.type === "dynamiczone") {
2843
- removeOperator(key2);
2844
- } else if (attribute.type === "password") {
2845
- removeOperator(key2);
2846
- } else {
2847
- filters2[key2] = convertAndSanitizeFilters(value2, schema);
2747
+ return policy2.handler;
2748
+ };
2749
+ const createPolicy = (options) => {
2750
+ const { name = "unnamed", validator, handler } = options;
2751
+ const wrappedValidator = (config) => {
2752
+ if (validator) {
2753
+ try {
2754
+ validator(config);
2755
+ } catch (e) {
2756
+ throw new Error(`Invalid config passed to "${name}" policy.`);
2848
2757
  }
2849
- } else if (["$null", "$notNull"].includes(key2)) {
2850
- filters2[key2] = parseType({ type: "boolean", value: filters2[key2], forceCast: true });
2851
- } else if (fp.isObject(value2)) {
2852
- filters2[key2] = convertAndSanitizeFilters(value2, schema);
2853
2758
  }
2854
- if (isPlainObject(filters2[key2]) && fp.isEmpty(filters2[key2])) {
2855
- removeOperator(key2);
2856
- }
2857
- }
2858
- return filters2;
2759
+ };
2760
+ return {
2761
+ name,
2762
+ validator: wrappedValidator,
2763
+ handler
2764
+ };
2765
+ };
2766
+ const createPolicyContext = (type, ctx) => {
2767
+ return Object.assign(
2768
+ {
2769
+ is: fp.eq(type),
2770
+ get type() {
2771
+ return type;
2772
+ }
2773
+ },
2774
+ ctx
2775
+ );
2776
+ };
2777
+ const policy = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2778
+ __proto__: null,
2779
+ createPolicy,
2780
+ createPolicyContext,
2781
+ get: getPolicy,
2782
+ globalPolicy,
2783
+ resolve: resolvePolicies
2784
+ }, Symbol.toStringTag, { value: "Module" }));
2785
+ const nameToSlug = (name, options = { separator: "-" }) => slugify__default.default(name, options);
2786
+ const nameToCollectionName = (name) => slugify__default.default(name, { separator: "_" });
2787
+ const toRegressedEnumValue = (value) => slugify__default.default(value, {
2788
+ decamelize: false,
2789
+ lowercase: false,
2790
+ separator: "_"
2791
+ });
2792
+ const getCommonPath = (...paths) => {
2793
+ const [segments, ...otherSegments] = paths.map((it) => ___default.default.split(it, "/"));
2794
+ return ___default.default.join(
2795
+ ___default.default.takeWhile(segments, (str, index2) => otherSegments.every((it) => it[index2] === str)),
2796
+ "/"
2797
+ );
2798
+ };
2799
+ const isEqual = (a, b) => String(a) === String(b);
2800
+ const isCamelCase = (value) => /^[a-z][a-zA-Z0-9]+$/.test(value);
2801
+ const isKebabCase = (value) => /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/.test(value);
2802
+ const startsWithANumber = (value) => /^[0-9]/.test(value);
2803
+ const joinBy = (joint, ...args) => {
2804
+ const trim = fp.trimChars(joint);
2805
+ const trimEnd = fp.trimCharsEnd(joint);
2806
+ const trimStart = fp.trimCharsStart(joint);
2807
+ return args.reduce((url, path, index2) => {
2808
+ if (args.length === 1)
2809
+ return path;
2810
+ if (index2 === 0)
2811
+ return trimEnd(path);
2812
+ if (index2 === args.length - 1)
2813
+ return url + joint + trimStart(path);
2814
+ return url + joint + trim(path);
2815
+ }, "");
2859
2816
  };
2860
- const convertPublicationStateParams = (schema, params = {}, query = {}) => {
2861
- if (!schema) {
2862
- return;
2863
- }
2864
- const { publicationState } = params;
2865
- if (!___default.default.isNil(publicationState)) {
2866
- if (!constants$1.DP_PUB_STATES.includes(publicationState)) {
2867
- throw new Error(
2868
- `Invalid publicationState. Expected one of 'preview','live' received: ${publicationState}.`
2869
- );
2870
- }
2871
- query.filters = ({ meta }) => {
2872
- if (publicationState === "live" && fp.has(PUBLISHED_AT_ATTRIBUTE, meta.attributes)) {
2873
- return { [PUBLISHED_AT_ATTRIBUTE]: { $notNull: true } };
2874
- }
2875
- };
2876
- }
2817
+ const toKebabCase = (value) => _$1.kebabCase(value);
2818
+ const strings = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2819
+ __proto__: null,
2820
+ getCommonPath,
2821
+ isCamelCase,
2822
+ isEqual,
2823
+ isKebabCase,
2824
+ joinBy,
2825
+ nameToCollectionName,
2826
+ nameToSlug,
2827
+ startsWithANumber,
2828
+ toKebabCase,
2829
+ toRegressedEnumValue
2830
+ }, Symbol.toStringTag, { value: "Module" }));
2831
+ const castIncludes = (arr, val, cast) => arr.map((val2) => cast(val2)).includes(cast(val));
2832
+ const includesString = (arr, val) => castIncludes(arr, val, String);
2833
+ const arrays = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2834
+ __proto__: null,
2835
+ includesString
2836
+ }, Symbol.toStringTag, { value: "Module" }));
2837
+ const keysDeep = (obj, path = []) => !___default.default.isObject(obj) ? [path.join(".")] : ___default.default.reduce(
2838
+ obj,
2839
+ (acc, next, key) => ___default.default.concat(acc, keysDeep(next, [...path, key])),
2840
+ []
2841
+ );
2842
+ const objects = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2843
+ __proto__: null,
2844
+ keysDeep
2845
+ }, Symbol.toStringTag, { value: "Module" }));
2846
+ const timestampCode = (date) => {
2847
+ const referDate = date ?? /* @__PURE__ */ new Date();
2848
+ return referDate.getTime().toString(36);
2877
2849
  };
2878
- const transformParamsToQuery = (uid, params) => {
2879
- const schema = strapi.getModel(uid);
2880
- const query = {};
2881
- const { _q, sort: sort2, filters: filters2, fields: fields2, populate: populate2, page, pageSize, start, limit } = params;
2882
- if (!fp.isNil(_q)) {
2883
- query._q = _q;
2884
- }
2885
- if (!fp.isNil(sort2)) {
2886
- query.orderBy = convertSortQueryParams(sort2);
2887
- }
2888
- if (!fp.isNil(filters2)) {
2889
- query.where = convertFiltersQueryParams(filters2, schema);
2850
+ const dates = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2851
+ __proto__: null,
2852
+ timestampCode
2853
+ }, Symbol.toStringTag, { value: "Module" }));
2854
+ const { toString } = Object.prototype;
2855
+ const errorToString = Error.prototype.toString;
2856
+ const regExpToString = RegExp.prototype.toString;
2857
+ const symbolToString = typeof Symbol !== "undefined" ? Symbol.prototype.toString : () => "";
2858
+ const SYMBOL_REGEXP = /^Symbol\((.*)\)(.*)$/;
2859
+ function printNumber(val) {
2860
+ if (val != +val)
2861
+ return "NaN";
2862
+ const isNegativeZero = val === 0 && 1 / val < 0;
2863
+ return isNegativeZero ? "-0" : `${val}`;
2864
+ }
2865
+ function printSimpleValue(val, quoteStrings = false) {
2866
+ if (val == null || val === true || val === false)
2867
+ return `${val}`;
2868
+ if (typeof val === "number")
2869
+ return printNumber(val);
2870
+ if (typeof val === "string")
2871
+ return quoteStrings ? `"${val}"` : val;
2872
+ if (typeof val === "function")
2873
+ return `[Function ${val.name || "anonymous"}]`;
2874
+ if (typeof val === "symbol")
2875
+ return symbolToString.call(val).replace(SYMBOL_REGEXP, "Symbol($1)");
2876
+ const tag = toString.call(val).slice(8, -1);
2877
+ if (tag === "Date") {
2878
+ const v = val;
2879
+ return Number.isNaN(v.getTime()) ? `${v}` : v.toISOString();
2890
2880
  }
2891
- if (!fp.isNil(fields2)) {
2892
- query.select = convertFieldsQueryParams(fields2);
2881
+ if (tag === "Error" || val instanceof Error)
2882
+ return `[${errorToString.call(val)}]`;
2883
+ if (tag === "RegExp")
2884
+ return regExpToString.call(val);
2885
+ return null;
2886
+ }
2887
+ function printValue(value, quoteStrings) {
2888
+ const result = printSimpleValue(value, quoteStrings);
2889
+ if (result !== null)
2890
+ return result;
2891
+ return JSON.stringify(
2892
+ value,
2893
+ function replacer(key, value2) {
2894
+ const result2 = printSimpleValue(this[key], quoteStrings);
2895
+ if (result2 !== null)
2896
+ return result2;
2897
+ return value2;
2898
+ },
2899
+ 2
2900
+ );
2901
+ }
2902
+ const strapiID = () => new StrapiIDSchema();
2903
+ const isNotNilTest = (value) => !___default.default.isNil(value);
2904
+ const isNotNullTest = (value) => !___default.default.isNull(value);
2905
+ yup__namespace.addMethod(yup__namespace.mixed, "notNil", function isNotNill(msg = "${path} must be defined.") {
2906
+ return this.test("defined", msg, isNotNilTest);
2907
+ });
2908
+ yup__namespace.addMethod(yup__namespace.mixed, "notNull", function isNotNull(msg = "${path} cannot be null.") {
2909
+ return this.test("defined", msg, isNotNullTest);
2910
+ });
2911
+ yup__namespace.addMethod(yup__namespace.mixed, "isFunction", function isFunction(message = "${path} is not a function") {
2912
+ return this.test(
2913
+ "is a function",
2914
+ message,
2915
+ (value) => ___default.default.isUndefined(value) || ___default.default.isFunction(value)
2916
+ );
2917
+ });
2918
+ yup__namespace.addMethod(
2919
+ yup__namespace.string,
2920
+ "isCamelCase",
2921
+ function isCamelCase$1(message = "${path} is not in camel case (anExampleOfCamelCase)") {
2922
+ return this.test(
2923
+ "is in camelCase",
2924
+ message,
2925
+ (value) => value ? isCamelCase(value) : true
2926
+ );
2893
2927
  }
2894
- if (!fp.isNil(populate2)) {
2895
- query.populate = convertPopulateQueryParams(populate2, schema);
2928
+ );
2929
+ yup__namespace.addMethod(
2930
+ yup__namespace.string,
2931
+ "isKebabCase",
2932
+ function isKebabCase$1(message = "${path} is not in kebab case (an-example-of-kebab-case)") {
2933
+ return this.test(
2934
+ "is in kebab-case",
2935
+ message,
2936
+ (value) => value ? isKebabCase(value) : true
2937
+ );
2896
2938
  }
2897
- validatePaginationParams(page, pageSize, start, limit);
2898
- if (!fp.isNil(page)) {
2899
- query.page = convertPageQueryParams(page);
2939
+ );
2940
+ yup__namespace.addMethod(
2941
+ yup__namespace.object,
2942
+ "onlyContainsFunctions",
2943
+ function onlyContainsFunctions(message = "${path} contains values that are not functions") {
2944
+ return this.test(
2945
+ "only contains functions",
2946
+ message,
2947
+ (value) => ___default.default.isUndefined(value) || value && Object.values(value).every(___default.default.isFunction)
2948
+ );
2900
2949
  }
2901
- if (!fp.isNil(pageSize)) {
2902
- query.pageSize = convertPageSizeQueryParams(pageSize, page);
2950
+ );
2951
+ yup__namespace.addMethod(
2952
+ yup__namespace.array,
2953
+ "uniqueProperty",
2954
+ function uniqueProperty(propertyName, message) {
2955
+ return this.test("unique", message, function unique(list) {
2956
+ const errors2 = [];
2957
+ list?.forEach((element, index2) => {
2958
+ const sameElements = list.filter(
2959
+ (e) => fp.get(propertyName, e) === fp.get(propertyName, element)
2960
+ );
2961
+ if (sameElements.length > 1) {
2962
+ errors2.push(
2963
+ this.createError({
2964
+ path: `${this.path}[${index2}].${propertyName}`,
2965
+ message
2966
+ })
2967
+ );
2968
+ }
2969
+ });
2970
+ if (errors2.length) {
2971
+ throw new yup__namespace.ValidationError(errors2);
2972
+ }
2973
+ return true;
2974
+ });
2903
2975
  }
2904
- if (!fp.isNil(start)) {
2905
- query.offset = convertStartQueryParams(start);
2976
+ );
2977
+ class StrapiIDSchema extends yup__namespace.MixedSchema {
2978
+ constructor() {
2979
+ super({ type: "strapiID" });
2906
2980
  }
2907
- if (!fp.isNil(limit)) {
2908
- query.limit = convertLimitQueryParams(limit);
2981
+ _typeCheck(value) {
2982
+ return typeof value === "string" || fp.isNumber(value) && fp.isInteger(value) && value >= 0;
2909
2983
  }
2910
- convertPublicationStateParams(schema, params, query);
2911
- return query;
2912
- };
2913
- const convertQueryParams = {
2914
- convertSortQueryParams,
2915
- convertStartQueryParams,
2916
- convertLimitQueryParams,
2917
- convertPopulateQueryParams,
2918
- convertFiltersQueryParams,
2919
- convertFieldsQueryParams,
2920
- convertPublicationStateParams,
2921
- transformParamsToQuery
2922
- };
2923
- function importDefault(modName) {
2924
- const mod = require(modName);
2925
- return mod && mod.__esModule ? mod.default : mod;
2926
2984
  }
2927
- const createStrictInterpolationRegExp = (allowedVariableNames, flags) => {
2928
- const oneOfVariables = allowedVariableNames.join("|");
2929
- return new RegExp(`<%=\\s*(${oneOfVariables})\\s*%>`, flags);
2930
- };
2931
- const createLooseInterpolationRegExp = (flags) => new RegExp(/<%=([\s\S]+?)%>/, flags);
2932
- const template = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2933
- __proto__: null,
2934
- createLooseInterpolationRegExp,
2935
- createStrictInterpolationRegExp
2936
- }, Symbol.toStringTag, { value: "Module" }));
2937
- const kbytesToBytes = (kbytes) => kbytes * 1e3;
2938
- const bytesToKbytes = (bytes) => Math.round(bytes / 1e3 * 100) / 100;
2939
- const bytesToHumanReadable = (bytes) => {
2940
- const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
2941
- if (bytes === 0)
2942
- return "0 Bytes";
2943
- const i = parseInt(`${Math.floor(Math.log(bytes) / Math.log(1e3))}`, 10);
2944
- return `${Math.round(bytes / 1e3 ** i)} ${sizes[i]}`;
2945
- };
2946
- const streamToBuffer = (stream) => new Promise((resolve, reject) => {
2947
- const chunks = [];
2948
- stream.on("data", (chunk) => {
2949
- chunks.push(chunk);
2950
- });
2951
- stream.on("end", () => {
2952
- resolve(Buffer.concat(chunks));
2953
- });
2954
- stream.on("error", reject);
2955
- });
2956
- const getStreamSize = (stream) => new Promise((resolve, reject) => {
2957
- let size = 0;
2958
- stream.on("data", (chunk) => {
2959
- size += Buffer.byteLength(chunk);
2960
- });
2961
- stream.on("close", () => resolve(size));
2962
- stream.on("error", reject);
2963
- stream.resume();
2964
- });
2965
- function writableDiscardStream(options) {
2966
- return new node_stream.Writable({
2967
- ...options,
2968
- write(chunk, encding, callback) {
2969
- setImmediate(callback);
2985
+ yup__namespace.setLocale({
2986
+ mixed: {
2987
+ notType(options) {
2988
+ const { path, type, value, originalValue } = options;
2989
+ const isCast = originalValue != null && originalValue !== value;
2990
+ const msg = `${path} must be a \`${type}\` type, but the final value was: \`${printValue(value, true)}\`${isCast ? ` (cast from the value \`${printValue(originalValue, true)}\`).` : "."}`;
2991
+ return msg;
2970
2992
  }
2971
- });
2972
- }
2973
- const file = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2974
- __proto__: null,
2975
- bytesToHumanReadable,
2976
- bytesToKbytes,
2977
- getStreamSize,
2978
- kbytesToBytes,
2979
- streamToBuffer,
2980
- writableDiscardStream
2981
- }, Symbol.toStringTag, { value: "Module" }));
2982
- const webhookEvents = {
2983
- ENTRY_CREATE: "entry.create",
2984
- ENTRY_UPDATE: "entry.update",
2985
- ENTRY_DELETE: "entry.delete",
2986
- ENTRY_PUBLISH: "entry.publish",
2987
- ENTRY_UNPUBLISH: "entry.unpublish",
2988
- MEDIA_CREATE: "media.create",
2989
- MEDIA_UPDATE: "media.update",
2990
- MEDIA_DELETE: "media.delete"
2991
- };
2992
- const deprecatedWebhookEvents = new Proxy(webhookEvents, {
2993
- get(target, prop) {
2994
- console.warn(
2995
- "[deprecated] @strapi/utils/webhook will no longer exist in the next major release of Strapi. Instead, the webhookEvents object can be retrieved from strapi.webhookStore.allowedEvents"
2996
- );
2997
- return target[prop];
2998
2993
  }
2999
2994
  });
3000
- const webhook = {
3001
- webhookEvents: deprecatedWebhookEvents
2995
+ const yup = /* @__PURE__ */ _mergeNamespaces({
2996
+ __proto__: null,
2997
+ StrapiIDSchema,
2998
+ strapiID
2999
+ }, [yup__namespace]);
3000
+ const MANY_RELATIONS = ["oneToMany", "manyToMany"];
3001
+ const getRelationalFields = (contentType) => {
3002
+ return Object.keys(contentType.attributes).filter((attributeName) => {
3003
+ return contentType.attributes[attributeName].type === "relation";
3004
+ });
3002
3005
  };
3006
+ const isOneToAny = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "oneToMany"].includes(attribute.relation);
3007
+ const isManyToAny = (attribute) => isRelationalAttribute(attribute) && ["manyToMany", "manyToOne"].includes(attribute.relation);
3008
+ const isAnyToOne = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "manyToOne"].includes(attribute.relation);
3009
+ const isAnyToMany = (attribute) => isRelationalAttribute(attribute) && ["oneToMany", "manyToMany"].includes(attribute.relation);
3010
+ const constants = {
3011
+ MANY_RELATIONS
3012
+ };
3013
+ const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3014
+ __proto__: null,
3015
+ constants,
3016
+ getRelationalFields,
3017
+ isAnyToMany,
3018
+ isAnyToOne,
3019
+ isManyToAny,
3020
+ isOneToAny
3021
+ }, Symbol.toStringTag, { value: "Module" }));
3022
+ exports.arrays = arrays;
3023
+ exports.async = async;
3003
3024
  exports.contentTypes = contentTypes;
3004
3025
  exports.convertQueryParams = convertQueryParams;
3026
+ exports.dates = dates;
3005
3027
  exports.env = env;
3006
3028
  exports.errors = errors;
3007
- exports.escapeQuery = escapeQuery;
3008
3029
  exports.file = file;
3009
- exports.forEachAsync = forEachAsync;
3010
- exports.generateTimestampCode = generateTimestampCode;
3011
- exports.getAbsoluteAdminUrl = getAbsoluteAdminUrl;
3012
- exports.getAbsoluteServerUrl = getAbsoluteServerUrl;
3013
- exports.getCommonBeginning = getCommonBeginning;
3014
- exports.getConfigUrls = getConfigUrls;
3015
- exports.handleYupError = handleYupError;
3016
3030
  exports.hooks = hooks;
3017
3031
  exports.importDefault = importDefault;
3018
- exports.isCamelCase = isCamelCase;
3019
- exports.isKebabCase = isKebabCase;
3020
3032
  exports.isOperator = isOperator;
3021
3033
  exports.isOperatorOfType = isOperatorOfType;
3022
- exports.joinBy = joinBy;
3023
- exports.keysDeep = keysDeep;
3024
- exports.mapAsync = mapAsync;
3025
- exports.nameToCollectionName = nameToCollectionName;
3026
- exports.nameToSlug = nameToSlug;
3034
+ exports.machineID = machineId;
3035
+ exports.objects = objects;
3036
+ exports.packageManager = packageManager;
3027
3037
  exports.pagination = pagination;
3028
- exports.parseMultipartData = parseMultipartData;
3029
3038
  exports.parseType = parseType;
3030
- exports.pipeAsync = pipeAsync;
3031
3039
  exports.policy = policy;
3032
3040
  exports.providerFactory = providerFactory;
3033
- exports.reduceAsync = reduceAsync;
3034
3041
  exports.relations = relations;
3035
- exports.removeUndefined = removeUndefined;
3036
3042
  exports.sanitize = index$1;
3037
3043
  exports.setCreatorFields = setCreatorFields;
3038
- exports.startsWithANumber = startsWithANumber;
3039
- exports.stringEquals = stringEquals;
3040
- exports.stringIncludes = stringIncludes;
3044
+ exports.strings = strings;
3041
3045
  exports.template = template;
3042
- exports.templateConfiguration = templateConfiguration;
3043
- exports.toKebabCase = toKebabCase;
3044
- exports.toRegressedEnumValue = toRegressedEnumValue;
3045
3046
  exports.traverse = index$2;
3046
3047
  exports.traverseEntity = traverseEntity$1;
3047
3048
  exports.validate = index;
3048
3049
  exports.validateYupSchema = validateYupSchema;
3049
3050
  exports.validateYupSchemaSync = validateYupSchemaSync;
3050
- exports.webhook = webhook;
3051
3051
  exports.yup = yup;
3052
3052
  //# sourceMappingURL=index.js.map