@strapi/utils 5.0.0-rc.22 → 5.0.0-rc.23

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.
package/dist/index.js CHANGED
@@ -1335,6 +1335,32 @@ const visitor$7 = ({ schema, key, attribute }, { remove }) => {
1335
1335
  remove(key);
1336
1336
  }
1337
1337
  };
1338
+ const MANY_RELATIONS = ["oneToMany", "manyToMany"];
1339
+ const getRelationalFields = (contentType) => {
1340
+ return Object.keys(contentType.attributes).filter((attributeName) => {
1341
+ return contentType.attributes[attributeName].type === "relation";
1342
+ });
1343
+ };
1344
+ const isOneToAny = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "oneToMany"].includes(attribute.relation);
1345
+ const isManyToAny = (attribute) => isRelationalAttribute(attribute) && ["manyToMany", "manyToOne"].includes(attribute.relation);
1346
+ const isAnyToOne = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "manyToOne"].includes(attribute.relation);
1347
+ const isAnyToMany = (attribute) => isRelationalAttribute(attribute) && ["oneToMany", "manyToMany"].includes(attribute.relation);
1348
+ const constants = {
1349
+ MANY_RELATIONS
1350
+ };
1351
+ const VALID_RELATION_ORDERING_KEYS = {
1352
+ strict: fp.isBoolean
1353
+ };
1354
+ const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1355
+ __proto__: null,
1356
+ VALID_RELATION_ORDERING_KEYS,
1357
+ constants,
1358
+ getRelationalFields,
1359
+ isAnyToMany,
1360
+ isAnyToOne,
1361
+ isManyToAny,
1362
+ isOneToAny
1363
+ }, Symbol.toStringTag, { value: "Module" }));
1338
1364
  const ACTIONS_TO_VERIFY$1 = ["find"];
1339
1365
  const { CREATED_BY_ATTRIBUTE: CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE: UPDATED_BY_ATTRIBUTE$1 } = constants$1;
1340
1366
  const removeRestrictedRelations = (auth) => async ({ data, key, attribute, schema }, { remove, set }) => {
@@ -1346,19 +1372,57 @@ const removeRestrictedRelations = (auth) => async ({ data, key, attribute, schem
1346
1372
  return;
1347
1373
  }
1348
1374
  const handleMorphRelation = async () => {
1349
- const newMorphValue = [];
1350
- for (const element of data[key]) {
1375
+ const elements = data[key];
1376
+ if ("connect" in elements || "set" in elements || "disconnect" in elements) {
1377
+ const newValue = {};
1378
+ const connect = await handleMorphElements(elements.connect || []);
1379
+ const relSet = await handleMorphElements(elements.set || []);
1380
+ const disconnect = await handleMorphElements(elements.disconnect || []);
1381
+ if (connect.length > 0) {
1382
+ newValue.connect = connect;
1383
+ }
1384
+ if (relSet.length > 0) {
1385
+ newValue.set = relSet;
1386
+ }
1387
+ if (disconnect.length > 0) {
1388
+ newValue.disconnect = disconnect;
1389
+ }
1390
+ if ("options" in elements && typeof elements.options === "object" && elements.options !== null) {
1391
+ const filteredOptions = {};
1392
+ Object.keys(elements.options).forEach((key2) => {
1393
+ const validator = VALID_RELATION_ORDERING_KEYS[key2];
1394
+ if (validator && validator(elements.options[key2])) {
1395
+ filteredOptions[key2] = elements.options[key2];
1396
+ }
1397
+ });
1398
+ newValue.options = filteredOptions;
1399
+ }
1400
+ set(key, newValue);
1401
+ } else {
1402
+ const newMorphValue = await handleMorphElements(elements);
1403
+ if (newMorphValue.length === 0) {
1404
+ remove(key);
1405
+ } else {
1406
+ set(key, newMorphValue);
1407
+ }
1408
+ }
1409
+ };
1410
+ const handleMorphElements = async (elements) => {
1411
+ const allowedElements = [];
1412
+ if (!fp.isArray(elements)) {
1413
+ return allowedElements;
1414
+ }
1415
+ for (const element of elements) {
1416
+ if (!fp.isObject(element) || !("__type" in element)) {
1417
+ continue;
1418
+ }
1351
1419
  const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${element.__type}.${action}`);
1352
1420
  const isAllowed = await hasAccessToSomeScopes$1(scopes, auth);
1353
1421
  if (isAllowed) {
1354
- newMorphValue.push(element);
1422
+ allowedElements.push(element);
1355
1423
  }
1356
1424
  }
1357
- if (newMorphValue.length === 0) {
1358
- remove(key);
1359
- } else {
1360
- set(key, newMorphValue);
1361
- }
1425
+ return allowedElements;
1362
1426
  };
1363
1427
  const handleRegularRelation = async () => {
1364
1428
  const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${attribute.target}.${action}`);
@@ -2229,7 +2293,40 @@ const throwRestrictedRelations = (auth) => async ({ data, key, attribute, schema
2229
2293
  return;
2230
2294
  }
2231
2295
  const handleMorphRelation = async () => {
2232
- for (const element of data[key]) {
2296
+ const elements = data[key];
2297
+ if ("connect" in elements || "set" in elements || "disconnect" in elements || "options" in elements) {
2298
+ await handleMorphElements(elements.connect || []);
2299
+ await handleMorphElements(elements.set || []);
2300
+ await handleMorphElements(elements.disconnect || []);
2301
+ if ("options" in elements) {
2302
+ if (elements.options === null || elements.options === void 0) {
2303
+ return;
2304
+ }
2305
+ if (typeof elements.options !== "object") {
2306
+ throwInvalidKey({ key, path: path.attribute });
2307
+ }
2308
+ const optionKeys = Object.keys(elements.options);
2309
+ for (const key2 of optionKeys) {
2310
+ if (!(key2 in VALID_RELATION_ORDERING_KEYS)) {
2311
+ throwInvalidKey({ key: key2, path: path.attribute });
2312
+ }
2313
+ if (!VALID_RELATION_ORDERING_KEYS[key2](elements.options[key2])) {
2314
+ throwInvalidKey({ key: key2, path: path.attribute });
2315
+ }
2316
+ }
2317
+ }
2318
+ } else {
2319
+ await handleMorphElements(elements);
2320
+ }
2321
+ };
2322
+ const handleMorphElements = async (elements) => {
2323
+ if (!fp.isArray(elements)) {
2324
+ throwInvalidKey({ key, path: path.attribute });
2325
+ }
2326
+ for (const element of elements) {
2327
+ if (!fp.isObject(element) || !("__type" in element)) {
2328
+ throwInvalidKey({ key, path: path.attribute });
2329
+ }
2233
2330
  const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);
2234
2331
  const isAllowed = await hasAccessToSomeScopes(scopes, auth);
2235
2332
  if (!isAllowed) {
@@ -3274,28 +3371,6 @@ const yup = /* @__PURE__ */ _mergeNamespaces({
3274
3371
  StrapiIDSchema,
3275
3372
  strapiID
3276
3373
  }, [yup__namespace]);
3277
- const MANY_RELATIONS = ["oneToMany", "manyToMany"];
3278
- const getRelationalFields = (contentType) => {
3279
- return Object.keys(contentType.attributes).filter((attributeName) => {
3280
- return contentType.attributes[attributeName].type === "relation";
3281
- });
3282
- };
3283
- const isOneToAny = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "oneToMany"].includes(attribute.relation);
3284
- const isManyToAny = (attribute) => isRelationalAttribute(attribute) && ["manyToMany", "manyToOne"].includes(attribute.relation);
3285
- const isAnyToOne = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "manyToOne"].includes(attribute.relation);
3286
- const isAnyToMany = (attribute) => isRelationalAttribute(attribute) && ["oneToMany", "manyToMany"].includes(attribute.relation);
3287
- const constants = {
3288
- MANY_RELATIONS
3289
- };
3290
- const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3291
- __proto__: null,
3292
- constants,
3293
- getRelationalFields,
3294
- isAnyToMany,
3295
- isAnyToOne,
3296
- isManyToAny,
3297
- isOneToAny
3298
- }, Symbol.toStringTag, { value: "Module" }));
3299
3374
  const validateZod = (schema) => (data) => {
3300
3375
  try {
3301
3376
  return schema.parse(data);