@strapi/utils 5.0.0-rc.9 → 5.0.1

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}`);
@@ -1884,10 +1948,17 @@ const populate = traverseFactory().intercept(isStringArray$1, async (visitor2, o
1884
1948
  }
1885
1949
  });
1886
1950
  const traverseQueryPopulate = fp.curry(populate.traverse);
1887
- const isStringArray = (value) => fp.isArray(value) && value.every(fp.isString);
1951
+ const isStringArray = (value) => {
1952
+ return fp.isArray(value) && value.every(fp.isString);
1953
+ };
1888
1954
  const fields = traverseFactory().intercept(isStringArray, async (visitor2, options, fields2, { recurse }) => {
1889
1955
  return Promise.all(fields2.map((field) => recurse(visitor2, options, field)));
1890
- }).intercept((value) => fp.eq("*", value), fp.constant("*")).parse(fp.isString, () => ({
1956
+ }).intercept(
1957
+ (value) => fp.isString(value) && value.includes(","),
1958
+ (visitor2, options, fields2, { recurse }) => {
1959
+ return Promise.all(fields2.split(",").map((field) => recurse(visitor2, options, field)));
1960
+ }
1961
+ ).intercept((value) => fp.eq("*", value), fp.constant("*")).parse(fp.isString, () => ({
1891
1962
  transform: fp.trim,
1892
1963
  remove(key, data) {
1893
1964
  return data === key ? void 0 : data;
@@ -2188,6 +2259,15 @@ const throwInvalidKey = ({ key, path }) => {
2188
2259
  path
2189
2260
  });
2190
2261
  };
2262
+ const asyncCurry = (fn) => {
2263
+ const curried = (...args) => {
2264
+ if (args.length >= fn.length) {
2265
+ return fn(...args);
2266
+ }
2267
+ return (...moreArgs) => curried(...args, ...moreArgs);
2268
+ };
2269
+ return curried;
2270
+ };
2191
2271
  const visitor$3 = ({ key, attribute, path }) => {
2192
2272
  if (attribute?.type === "password") {
2193
2273
  throwInvalidKey({ key, path: path.attribute });
@@ -2213,7 +2293,40 @@ const throwRestrictedRelations = (auth) => async ({ data, key, attribute, schema
2213
2293
  return;
2214
2294
  }
2215
2295
  const handleMorphRelation = async () => {
2216
- 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
+ }
2217
2330
  const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);
2218
2331
  const isAllowed = await hasAccessToSomeScopes(scopes, auth);
2219
2332
  if (!isAllowed) {
@@ -2353,154 +2466,294 @@ const throwPasswords = (ctx) => async (entity) => {
2353
2466
  }
2354
2467
  return traverseEntity$1(visitor$3, ctx, entity);
2355
2468
  };
2356
- const defaultValidateFilters = fp.curry((ctx, filters2) => {
2357
- if (!ctx.schema) {
2358
- throw new Error("Missing schema in defaultValidateFilters");
2469
+ const FILTER_TRAVERSALS = [
2470
+ "nonAttributesOperators",
2471
+ "dynamicZones",
2472
+ "morphRelations",
2473
+ "passwords",
2474
+ "private"
2475
+ ];
2476
+ const validateFilters = asyncCurry(
2477
+ async (ctx, filters2, include) => {
2478
+ if (!ctx.schema) {
2479
+ throw new Error("Missing schema in defaultValidateFilters");
2480
+ }
2481
+ const functionsToApply = [];
2482
+ if (include.includes("nonAttributesOperators")) {
2483
+ functionsToApply.push(
2484
+ traverseQueryFilters(({ key, attribute, path }) => {
2485
+ if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
2486
+ return;
2487
+ }
2488
+ const isAttribute = !!attribute;
2489
+ if (!isAttribute && !isOperator(key)) {
2490
+ throwInvalidKey({ key, path: path.attribute });
2491
+ }
2492
+ }, ctx)
2493
+ );
2494
+ }
2495
+ if (include.includes("dynamicZones")) {
2496
+ functionsToApply.push(traverseQueryFilters(visitor, ctx));
2497
+ }
2498
+ if (include.includes("morphRelations")) {
2499
+ functionsToApply.push(traverseQueryFilters(visitor$1, ctx));
2500
+ }
2501
+ if (include.includes("passwords")) {
2502
+ functionsToApply.push(traverseQueryFilters(visitor$3, ctx));
2503
+ }
2504
+ if (include.includes("private")) {
2505
+ functionsToApply.push(traverseQueryFilters(visitor$2, ctx));
2506
+ }
2507
+ if (functionsToApply.length === 0) {
2508
+ return filters2;
2509
+ }
2510
+ return pipe(...functionsToApply)(filters2);
2359
2511
  }
2360
- return pipe(
2361
- // keys that are not attributes or valid operators
2362
- traverseQueryFilters(({ key, attribute, path }) => {
2363
- if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
2364
- return;
2365
- }
2366
- const isAttribute = !!attribute;
2367
- if (!isAttribute && !isOperator(key)) {
2368
- throwInvalidKey({ key, path: path.attribute });
2369
- }
2370
- }, ctx),
2371
- // dynamic zones from filters
2372
- traverseQueryFilters(visitor, ctx),
2373
- // morphTo relations from filters; because you can't have deep filtering on morph relations
2374
- traverseQueryFilters(visitor$1, ctx),
2375
- // passwords from filters
2376
- traverseQueryFilters(visitor$3, ctx),
2377
- // private from filters
2378
- traverseQueryFilters(visitor$2, ctx)
2379
- // we allow empty objects to validate and only sanitize them out, so that users may write "lazy" queries without checking their params exist
2380
- )(filters2);
2512
+ );
2513
+ const defaultValidateFilters = asyncCurry(async (ctx, filters2) => {
2514
+ return validateFilters(ctx, filters2, FILTER_TRAVERSALS);
2381
2515
  });
2382
- const defaultValidateSort = fp.curry((ctx, sort2) => {
2383
- if (!ctx.schema) {
2384
- throw new Error("Missing schema in defaultValidateSort");
2516
+ const SORT_TRAVERSALS = [
2517
+ "nonAttributesOperators",
2518
+ "dynamicZones",
2519
+ "morphRelations",
2520
+ "passwords",
2521
+ "private",
2522
+ "nonScalarEmptyKeys"
2523
+ ];
2524
+ const validateSort = asyncCurry(
2525
+ async (ctx, sort2, include) => {
2526
+ if (!ctx.schema) {
2527
+ throw new Error("Missing schema in defaultValidateSort");
2528
+ }
2529
+ const functionsToApply = [];
2530
+ if (include.includes("nonAttributesOperators")) {
2531
+ functionsToApply.push(
2532
+ traverseQuerySort(({ key, attribute, path }) => {
2533
+ if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
2534
+ return;
2535
+ }
2536
+ if (!attribute) {
2537
+ throwInvalidKey({ key, path: path.attribute });
2538
+ }
2539
+ }, ctx)
2540
+ );
2541
+ }
2542
+ if (include.includes("dynamicZones")) {
2543
+ functionsToApply.push(traverseQuerySort(visitor, ctx));
2544
+ }
2545
+ if (include.includes("morphRelations")) {
2546
+ functionsToApply.push(traverseQuerySort(visitor$1, ctx));
2547
+ }
2548
+ if (include.includes("passwords")) {
2549
+ functionsToApply.push(traverseQuerySort(visitor$3, ctx));
2550
+ }
2551
+ if (include.includes("private")) {
2552
+ functionsToApply.push(traverseQuerySort(visitor$2, ctx));
2553
+ }
2554
+ if (include.includes("nonScalarEmptyKeys")) {
2555
+ functionsToApply.push(
2556
+ traverseQuerySort(({ key, attribute, value, path }) => {
2557
+ if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
2558
+ return;
2559
+ }
2560
+ if (!isScalarAttribute(attribute) && fp.isEmpty(value)) {
2561
+ throwInvalidKey({ key, path: path.attribute });
2562
+ }
2563
+ }, ctx)
2564
+ );
2565
+ }
2566
+ if (functionsToApply.length === 0) {
2567
+ return sort2;
2568
+ }
2569
+ return pipe(...functionsToApply)(sort2);
2385
2570
  }
2386
- return pipe(
2387
- // non attribute keys
2388
- traverseQuerySort(({ key, attribute, path }) => {
2389
- if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
2390
- return;
2391
- }
2392
- if (!attribute) {
2393
- throwInvalidKey({ key, path: path.attribute });
2394
- }
2395
- }, ctx),
2396
- // dynamic zones from sort
2397
- traverseQuerySort(visitor, ctx),
2398
- // morphTo relations from sort
2399
- traverseQuerySort(visitor$1, ctx),
2400
- // private from sort
2401
- traverseQuerySort(visitor$2, ctx),
2402
- // passwords from filters
2403
- traverseQuerySort(visitor$3, ctx),
2404
- // keys for empty non-scalar values
2405
- traverseQuerySort(({ key, attribute, value, path }) => {
2406
- if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
2407
- return;
2408
- }
2409
- if (!isScalarAttribute(attribute) && fp.isEmpty(value)) {
2410
- throwInvalidKey({ key, path: path.attribute });
2411
- }
2412
- }, ctx)
2413
- )(sort2);
2571
+ );
2572
+ const defaultValidateSort = asyncCurry(async (ctx, sort2) => {
2573
+ return validateSort(ctx, sort2, SORT_TRAVERSALS);
2414
2574
  });
2415
- const defaultValidateFields = fp.curry((ctx, fields2) => {
2416
- if (!ctx.schema) {
2417
- throw new Error("Missing schema in defaultValidateFields");
2575
+ const FIELDS_TRAVERSALS = ["scalarAttributes", "privateFields", "passwordFields"];
2576
+ const validateFields = asyncCurry(
2577
+ async (ctx, fields2, include) => {
2578
+ if (!ctx.schema) {
2579
+ throw new Error("Missing schema in defaultValidateFields");
2580
+ }
2581
+ const functionsToApply = [];
2582
+ if (include.includes("scalarAttributes")) {
2583
+ functionsToApply.push(
2584
+ traverseQueryFields(({ key, attribute, path }) => {
2585
+ if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
2586
+ return;
2587
+ }
2588
+ if (fp.isNil(attribute) || !isScalarAttribute(attribute)) {
2589
+ throwInvalidKey({ key, path: path.attribute });
2590
+ }
2591
+ }, ctx)
2592
+ );
2593
+ }
2594
+ if (include.includes("privateFields")) {
2595
+ functionsToApply.push(traverseQueryFields(visitor$2, ctx));
2596
+ }
2597
+ if (include.includes("passwordFields")) {
2598
+ functionsToApply.push(traverseQueryFields(visitor$3, ctx));
2599
+ }
2600
+ if (functionsToApply.length === 0) {
2601
+ return fields2;
2602
+ }
2603
+ return pipe(...functionsToApply)(fields2);
2418
2604
  }
2419
- return pipe(
2420
- // Only allow scalar attributes
2421
- traverseQueryFields(({ key, attribute, path }) => {
2422
- if ([ID_ATTRIBUTE$1, DOC_ID_ATTRIBUTE$1].includes(key)) {
2423
- return;
2424
- }
2425
- if (fp.isNil(attribute) || !isScalarAttribute(attribute)) {
2426
- throwInvalidKey({ key, path: path.attribute });
2427
- }
2428
- }, ctx),
2429
- // private fields
2430
- traverseQueryFields(visitor$2, ctx),
2431
- // password fields
2432
- traverseQueryFields(visitor$3, ctx)
2433
- )(fields2);
2605
+ );
2606
+ const defaultValidateFields = asyncCurry(async (ctx, fields2) => {
2607
+ return validateFields(ctx, fields2, FIELDS_TRAVERSALS);
2434
2608
  });
2435
- const defaultValidatePopulate = fp.curry((ctx, populate2) => {
2609
+ const POPULATE_TRAVERSALS = ["nonAttributesOperators", "private"];
2610
+ const validatePopulate = asyncCurry(
2611
+ async (ctx, populate2, includes) => {
2612
+ if (!ctx.schema) {
2613
+ throw new Error("Missing schema in defaultValidatePopulate");
2614
+ }
2615
+ const functionsToApply = [];
2616
+ functionsToApply.push(
2617
+ traverseQueryPopulate(async ({ key, path, value, schema, attribute, getModel }, { set }) => {
2618
+ if (attribute) {
2619
+ const isPopulatableAttribute = ["relation", "dynamiczone", "component", "media"].includes(
2620
+ attribute.type
2621
+ );
2622
+ if (!isPopulatableAttribute) {
2623
+ throwInvalidKey({ key, path: path.raw });
2624
+ }
2625
+ return;
2626
+ }
2627
+ if (key === "on") {
2628
+ if (!fp.isObject(value)) {
2629
+ return throwInvalidKey({ key, path: path.raw });
2630
+ }
2631
+ const targets = Object.keys(value);
2632
+ for (const target of targets) {
2633
+ const model = getModel(target);
2634
+ if (!model) {
2635
+ throwInvalidKey({ key: target, path: `${path.raw}.${target}` });
2636
+ }
2637
+ }
2638
+ return;
2639
+ }
2640
+ if (key === "" && value === "*") {
2641
+ return;
2642
+ }
2643
+ if (key === "count") {
2644
+ try {
2645
+ parseType({ type: "boolean", value });
2646
+ return;
2647
+ } catch {
2648
+ throwInvalidKey({ key, path: path.attribute });
2649
+ }
2650
+ }
2651
+ try {
2652
+ parseType({ type: "boolean", value: key });
2653
+ return;
2654
+ } catch {
2655
+ }
2656
+ if (key === "sort") {
2657
+ set(
2658
+ key,
2659
+ await validateSort(
2660
+ {
2661
+ schema,
2662
+ getModel
2663
+ },
2664
+ value,
2665
+ // pass the sort value
2666
+ includes?.sort || SORT_TRAVERSALS
2667
+ )
2668
+ );
2669
+ return;
2670
+ }
2671
+ if (key === "filters") {
2672
+ set(
2673
+ key,
2674
+ await validateFilters(
2675
+ {
2676
+ schema,
2677
+ getModel
2678
+ },
2679
+ value,
2680
+ // pass the filters value
2681
+ includes?.filters || FILTER_TRAVERSALS
2682
+ )
2683
+ );
2684
+ return;
2685
+ }
2686
+ if (key === "fields") {
2687
+ set(
2688
+ key,
2689
+ await validateFields(
2690
+ {
2691
+ schema,
2692
+ getModel
2693
+ },
2694
+ value,
2695
+ // pass the fields value
2696
+ includes?.fields || FIELDS_TRAVERSALS
2697
+ )
2698
+ );
2699
+ return;
2700
+ }
2701
+ if (key === "populate") {
2702
+ set(
2703
+ key,
2704
+ await validatePopulate(
2705
+ {
2706
+ schema,
2707
+ getModel
2708
+ },
2709
+ value,
2710
+ // pass the nested populate value
2711
+ includes
2712
+ // pass down the same includes object
2713
+ )
2714
+ );
2715
+ return;
2716
+ }
2717
+ if (includes?.populate?.includes("nonAttributesOperators")) {
2718
+ throwInvalidKey({ key, path: path.attribute });
2719
+ }
2720
+ }, ctx)
2721
+ );
2722
+ if (includes?.populate?.includes("private")) {
2723
+ functionsToApply.push(traverseQueryPopulate(visitor$2, ctx));
2724
+ }
2725
+ if (functionsToApply.length === 0) {
2726
+ return populate2;
2727
+ }
2728
+ return pipe(...functionsToApply)(populate2);
2729
+ }
2730
+ );
2731
+ const defaultValidatePopulate = asyncCurry(async (ctx, populate2) => {
2436
2732
  if (!ctx.schema) {
2437
2733
  throw new Error("Missing schema in defaultValidatePopulate");
2438
2734
  }
2439
- return pipe(
2440
- traverseQueryPopulate(async ({ key, value, schema, attribute, getModel }, { set }) => {
2441
- if (attribute) {
2442
- return;
2443
- }
2444
- if (key === "sort") {
2445
- set(
2446
- key,
2447
- await defaultValidateSort(
2448
- {
2449
- schema,
2450
- getModel
2451
- },
2452
- value
2453
- )
2454
- );
2455
- }
2456
- if (key === "filters") {
2457
- set(
2458
- key,
2459
- await defaultValidateFilters(
2460
- {
2461
- schema,
2462
- getModel
2463
- },
2464
- value
2465
- )
2466
- );
2467
- }
2468
- if (key === "fields") {
2469
- set(
2470
- key,
2471
- await defaultValidateFields(
2472
- {
2473
- schema,
2474
- getModel
2475
- },
2476
- value
2477
- )
2478
- );
2479
- }
2480
- if (key === "populate") {
2481
- set(
2482
- key,
2483
- await defaultValidatePopulate(
2484
- {
2485
- schema,
2486
- getModel
2487
- },
2488
- value
2489
- )
2490
- );
2491
- }
2492
- }, ctx),
2493
- // Remove private fields
2494
- traverseQueryPopulate(visitor$2, ctx)
2495
- )(populate2);
2735
+ return validatePopulate(ctx, populate2, {
2736
+ filters: FILTER_TRAVERSALS,
2737
+ sort: SORT_TRAVERSALS,
2738
+ fields: FIELDS_TRAVERSALS,
2739
+ populate: POPULATE_TRAVERSALS
2740
+ });
2496
2741
  });
2497
2742
  const validators = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2498
2743
  __proto__: null,
2744
+ FIELDS_TRAVERSALS,
2745
+ FILTER_TRAVERSALS,
2746
+ POPULATE_TRAVERSALS,
2747
+ SORT_TRAVERSALS,
2499
2748
  defaultValidateFields,
2500
2749
  defaultValidateFilters,
2501
2750
  defaultValidatePopulate,
2502
2751
  defaultValidateSort,
2503
- throwPasswords
2752
+ throwPasswords,
2753
+ validateFields,
2754
+ validateFilters,
2755
+ validatePopulate,
2756
+ validateSort
2504
2757
  }, Symbol.toStringTag, { value: "Module" }));
2505
2758
  const { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants$1;
2506
2759
  const createAPIValidators = (opts) => {
@@ -2555,24 +2808,24 @@ const createAPIValidators = (opts) => {
2555
2808
  }
2556
2809
  const { filters: filters2, sort: sort2, fields: fields2, populate: populate2 } = query;
2557
2810
  if (filters2) {
2558
- await validateFilters(filters2, schema, { auth });
2811
+ await validateFilters2(filters2, schema, { auth });
2559
2812
  }
2560
2813
  if (sort2) {
2561
- await validateSort(sort2, schema, { auth });
2814
+ await validateSort2(sort2, schema, { auth });
2562
2815
  }
2563
2816
  if (fields2) {
2564
- await validateFields(fields2, schema);
2817
+ await validateFields2(fields2, schema);
2565
2818
  }
2566
2819
  if (populate2 && populate2 !== "*") {
2567
- await validatePopulate(populate2, schema);
2820
+ await validatePopulate2(populate2, schema);
2568
2821
  }
2569
2822
  };
2570
- const validateFilters = async (filters2, schema, { auth } = {}) => {
2823
+ const validateFilters2 = async (filters2, schema, { auth } = {}) => {
2571
2824
  if (!schema) {
2572
2825
  throw new Error("Missing schema in validateFilters");
2573
2826
  }
2574
2827
  if (fp.isArray(filters2)) {
2575
- await Promise.all(filters2.map((filter) => validateFilters(filter, schema, { auth })));
2828
+ await Promise.all(filters2.map((filter) => validateFilters2(filter, schema, { auth })));
2576
2829
  return;
2577
2830
  }
2578
2831
  const transforms = [defaultValidateFilters({ schema, getModel })];
@@ -2594,7 +2847,7 @@ const createAPIValidators = (opts) => {
2594
2847
  throw e;
2595
2848
  }
2596
2849
  };
2597
- const validateSort = async (sort2, schema, { auth } = {}) => {
2850
+ const validateSort2 = async (sort2, schema, { auth } = {}) => {
2598
2851
  if (!schema) {
2599
2852
  throw new Error("Missing schema in validateSort");
2600
2853
  }
@@ -2617,7 +2870,7 @@ const createAPIValidators = (opts) => {
2617
2870
  throw e;
2618
2871
  }
2619
2872
  };
2620
- const validateFields = async (fields2, schema) => {
2873
+ const validateFields2 = async (fields2, schema) => {
2621
2874
  if (!schema) {
2622
2875
  throw new Error("Missing schema in validateFields");
2623
2876
  }
@@ -2632,7 +2885,7 @@ const createAPIValidators = (opts) => {
2632
2885
  throw e;
2633
2886
  }
2634
2887
  };
2635
- const validatePopulate = async (populate2, schema, { auth } = {}) => {
2888
+ const validatePopulate2 = async (populate2, schema, { auth } = {}) => {
2636
2889
  if (!schema) {
2637
2890
  throw new Error("Missing schema in sanitizePopulate");
2638
2891
  }
@@ -2658,10 +2911,10 @@ const createAPIValidators = (opts) => {
2658
2911
  return {
2659
2912
  input: validateInput,
2660
2913
  query: validateQuery,
2661
- filters: validateFilters,
2662
- sort: validateSort,
2663
- fields: validateFields,
2664
- populate: validatePopulate
2914
+ filters: validateFilters2,
2915
+ sort: validateSort2,
2916
+ fields: validateFields2,
2917
+ populate: validatePopulate2
2665
2918
  };
2666
2919
  };
2667
2920
  const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -3118,28 +3371,6 @@ const yup = /* @__PURE__ */ _mergeNamespaces({
3118
3371
  StrapiIDSchema,
3119
3372
  strapiID
3120
3373
  }, [yup__namespace]);
3121
- const MANY_RELATIONS = ["oneToMany", "manyToMany"];
3122
- const getRelationalFields = (contentType) => {
3123
- return Object.keys(contentType.attributes).filter((attributeName) => {
3124
- return contentType.attributes[attributeName].type === "relation";
3125
- });
3126
- };
3127
- const isOneToAny = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "oneToMany"].includes(attribute.relation);
3128
- const isManyToAny = (attribute) => isRelationalAttribute(attribute) && ["manyToMany", "manyToOne"].includes(attribute.relation);
3129
- const isAnyToOne = (attribute) => isRelationalAttribute(attribute) && ["oneToOne", "manyToOne"].includes(attribute.relation);
3130
- const isAnyToMany = (attribute) => isRelationalAttribute(attribute) && ["oneToMany", "manyToMany"].includes(attribute.relation);
3131
- const constants = {
3132
- MANY_RELATIONS
3133
- };
3134
- const relations = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3135
- __proto__: null,
3136
- constants,
3137
- getRelationalFields,
3138
- isAnyToMany,
3139
- isAnyToOne,
3140
- isManyToAny,
3141
- isOneToAny
3142
- }, Symbol.toStringTag, { value: "Module" }));
3143
3374
  const validateZod = (schema) => (data) => {
3144
3375
  try {
3145
3376
  return schema.parse(data);