@strapi/utils 5.0.0-rc.21 → 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.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _ from "lodash";
2
2
  import ___default, { kebabCase } from "lodash";
3
3
  import * as dates$1 from "date-fns";
4
- import { has, union, getOr, assoc, assign, cloneDeep, remove, eq, curry, isObject, isNil, clone, isArray, isEmpty, toPath, defaults, isString, get, toNumber, isInteger, pick, omit, trim, pipe as pipe$1, split, map as map$1, flatten, first, identity, constant, join, merge, trimChars, trimCharsEnd, trimCharsStart, isNumber } from "lodash/fp";
4
+ import { has, union, getOr, assoc, assign, cloneDeep, remove, eq, curry, isObject, isNil, clone, isArray, isEmpty, toPath, defaults, isString, get, toNumber, isInteger, isBoolean, pick, omit, trim, pipe as pipe$1, split, map as map$1, flatten, first, identity, constant, join, merge, trimChars, trimCharsEnd, trimCharsStart, isNumber } from "lodash/fp";
5
5
  import { randomUUID } from "crypto";
6
6
  import { machineIdSync } from "node-machine-id";
7
7
  import * as yup$1 from "yup";
@@ -1308,6 +1308,32 @@ const visitor$7 = ({ schema, key, attribute }, { remove: remove2 }) => {
1308
1308
  remove2(key);
1309
1309
  }
1310
1310
  };
1311
+ const MANY_RELATIONS = ["oneToMany", "manyToMany"];
1312
+ const getRelationalFields = (contentType) => {
1313
+ return Object.keys(contentType.attributes).filter((attributeName) => {
1314
+ return contentType.attributes[attributeName].type === "relation";
1315
+ });
1316
+ };
1317
+ const isOneToAny = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "oneToMany"].includes(attribute.relation);
1318
+ const isManyToAny = (attribute) => isRelationalAttribute(attribute) && ["manyToMany", "manyToOne"].includes(attribute.relation);
1319
+ const isAnyToOne = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "manyToOne"].includes(attribute.relation);
1320
+ const isAnyToMany = (attribute) => isRelationalAttribute(attribute) && ["oneToMany", "manyToMany"].includes(attribute.relation);
1321
+ const constants = {
1322
+ MANY_RELATIONS
1323
+ };
1324
+ const VALID_RELATION_ORDERING_KEYS = {
1325
+ strict: isBoolean
1326
+ };
1327
+ const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1328
+ __proto__: null,
1329
+ VALID_RELATION_ORDERING_KEYS,
1330
+ constants,
1331
+ getRelationalFields,
1332
+ isAnyToMany,
1333
+ isAnyToOne,
1334
+ isManyToAny,
1335
+ isOneToAny
1336
+ }, Symbol.toStringTag, { value: "Module" }));
1311
1337
  const ACTIONS_TO_VERIFY$1 = ["find"];
1312
1338
  const { CREATED_BY_ATTRIBUTE: CREATED_BY_ATTRIBUTE$1, UPDATED_BY_ATTRIBUTE: UPDATED_BY_ATTRIBUTE$1 } = constants$1;
1313
1339
  const removeRestrictedRelations = (auth) => async ({ data, key, attribute, schema }, { remove: remove2, set }) => {
@@ -1319,19 +1345,57 @@ const removeRestrictedRelations = (auth) => async ({ data, key, attribute, schem
1319
1345
  return;
1320
1346
  }
1321
1347
  const handleMorphRelation = async () => {
1322
- const newMorphValue = [];
1323
- for (const element of data[key]) {
1348
+ const elements = data[key];
1349
+ if ("connect" in elements || "set" in elements || "disconnect" in elements) {
1350
+ const newValue = {};
1351
+ const connect = await handleMorphElements(elements.connect || []);
1352
+ const relSet = await handleMorphElements(elements.set || []);
1353
+ const disconnect = await handleMorphElements(elements.disconnect || []);
1354
+ if (connect.length > 0) {
1355
+ newValue.connect = connect;
1356
+ }
1357
+ if (relSet.length > 0) {
1358
+ newValue.set = relSet;
1359
+ }
1360
+ if (disconnect.length > 0) {
1361
+ newValue.disconnect = disconnect;
1362
+ }
1363
+ if ("options" in elements && typeof elements.options === "object" && elements.options !== null) {
1364
+ const filteredOptions = {};
1365
+ Object.keys(elements.options).forEach((key2) => {
1366
+ const validator = VALID_RELATION_ORDERING_KEYS[key2];
1367
+ if (validator && validator(elements.options[key2])) {
1368
+ filteredOptions[key2] = elements.options[key2];
1369
+ }
1370
+ });
1371
+ newValue.options = filteredOptions;
1372
+ }
1373
+ set(key, newValue);
1374
+ } else {
1375
+ const newMorphValue = await handleMorphElements(elements);
1376
+ if (newMorphValue.length === 0) {
1377
+ remove2(key);
1378
+ } else {
1379
+ set(key, newMorphValue);
1380
+ }
1381
+ }
1382
+ };
1383
+ const handleMorphElements = async (elements) => {
1384
+ const allowedElements = [];
1385
+ if (!isArray(elements)) {
1386
+ return allowedElements;
1387
+ }
1388
+ for (const element of elements) {
1389
+ if (!isObject(element) || !("__type" in element)) {
1390
+ continue;
1391
+ }
1324
1392
  const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${element.__type}.${action}`);
1325
1393
  const isAllowed = await hasAccessToSomeScopes$1(scopes, auth);
1326
1394
  if (isAllowed) {
1327
- newMorphValue.push(element);
1395
+ allowedElements.push(element);
1328
1396
  }
1329
1397
  }
1330
- if (newMorphValue.length === 0) {
1331
- remove2(key);
1332
- } else {
1333
- set(key, newMorphValue);
1334
- }
1398
+ return allowedElements;
1335
1399
  };
1336
1400
  const handleRegularRelation = async () => {
1337
1401
  const scopes = ACTIONS_TO_VERIFY$1.map((action) => `${attribute.target}.${action}`);
@@ -2202,7 +2266,40 @@ const throwRestrictedRelations = (auth) => async ({ data, key, attribute, schema
2202
2266
  return;
2203
2267
  }
2204
2268
  const handleMorphRelation = async () => {
2205
- for (const element of data[key]) {
2269
+ const elements = data[key];
2270
+ if ("connect" in elements || "set" in elements || "disconnect" in elements || "options" in elements) {
2271
+ await handleMorphElements(elements.connect || []);
2272
+ await handleMorphElements(elements.set || []);
2273
+ await handleMorphElements(elements.disconnect || []);
2274
+ if ("options" in elements) {
2275
+ if (elements.options === null || elements.options === void 0) {
2276
+ return;
2277
+ }
2278
+ if (typeof elements.options !== "object") {
2279
+ throwInvalidKey({ key, path: path.attribute });
2280
+ }
2281
+ const optionKeys = Object.keys(elements.options);
2282
+ for (const key2 of optionKeys) {
2283
+ if (!(key2 in VALID_RELATION_ORDERING_KEYS)) {
2284
+ throwInvalidKey({ key: key2, path: path.attribute });
2285
+ }
2286
+ if (!VALID_RELATION_ORDERING_KEYS[key2](elements.options[key2])) {
2287
+ throwInvalidKey({ key: key2, path: path.attribute });
2288
+ }
2289
+ }
2290
+ }
2291
+ } else {
2292
+ await handleMorphElements(elements);
2293
+ }
2294
+ };
2295
+ const handleMorphElements = async (elements) => {
2296
+ if (!isArray(elements)) {
2297
+ throwInvalidKey({ key, path: path.attribute });
2298
+ }
2299
+ for (const element of elements) {
2300
+ if (!isObject(element) || !("__type" in element)) {
2301
+ throwInvalidKey({ key, path: path.attribute });
2302
+ }
2206
2303
  const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);
2207
2304
  const isAllowed = await hasAccessToSomeScopes(scopes, auth);
2208
2305
  if (!isAllowed) {
@@ -3247,28 +3344,6 @@ const yup = /* @__PURE__ */ _mergeNamespaces({
3247
3344
  StrapiIDSchema,
3248
3345
  strapiID
3249
3346
  }, [yup$1]);
3250
- const MANY_RELATIONS = ["oneToMany", "manyToMany"];
3251
- const getRelationalFields = (contentType) => {
3252
- return Object.keys(contentType.attributes).filter((attributeName) => {
3253
- return contentType.attributes[attributeName].type === "relation";
3254
- });
3255
- };
3256
- const isOneToAny = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "oneToMany"].includes(attribute.relation);
3257
- const isManyToAny = (attribute) => isRelationalAttribute(attribute) && ["manyToMany", "manyToOne"].includes(attribute.relation);
3258
- const isAnyToOne = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "manyToOne"].includes(attribute.relation);
3259
- const isAnyToMany = (attribute) => isRelationalAttribute(attribute) && ["oneToMany", "manyToMany"].includes(attribute.relation);
3260
- const constants = {
3261
- MANY_RELATIONS
3262
- };
3263
- const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3264
- __proto__: null,
3265
- constants,
3266
- getRelationalFields,
3267
- isAnyToMany,
3268
- isAnyToOne,
3269
- isManyToAny,
3270
- isOneToAny
3271
- }, Symbol.toStringTag, { value: "Module" }));
3272
3347
  const validateZod = (schema) => (data) => {
3273
3348
  try {
3274
3349
  return schema.parse(data);