@sanity/schema 5.0.0-next.0-9b570ece82-202507150640 → 5.0.0-next.6

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2016 - 2024 Sanity.io
3
+ Copyright (c) 2016 - 2025 Sanity.io
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,15 +1,33 @@
1
+ import startCase from "lodash/startCase.js";
1
2
  import omit from "lodash/omit.js";
2
3
  import pick from "lodash/pick.js";
3
- import { DEFAULT_OVERRIDEABLE_FIELDS, OWN_PROPS_NAME, resolveSearchConfigForBaseFieldPaths, resolveSearchConfig } from "./_chunks-es/resolve.mjs";
4
4
  import arrify from "arrify";
5
5
  import isUndefined from "lodash/isUndefined.js";
6
6
  import omitBy from "lodash/omitBy.js";
7
7
  import capitalize from "lodash/capitalize.js";
8
+ import isFinite from "lodash/isFinite.js";
9
+ import uniqBy from "lodash/uniqBy.js";
8
10
  import castArray from "lodash/castArray.js";
9
11
  import flatMap from "lodash/flatMap.js";
10
- import startCase from "lodash/startCase.js";
11
12
  import isPlainObject from "lodash/isPlainObject.js";
12
13
  import toPath from "lodash/toPath.js";
14
+ import cloneDeep from "lodash/cloneDeep.js";
15
+ const DEFAULT_OVERRIDEABLE_FIELDS = [
16
+ "jsonType",
17
+ "type",
18
+ "name",
19
+ "title",
20
+ "description",
21
+ "options",
22
+ "fieldsets",
23
+ "validation",
24
+ "readOnly",
25
+ "hidden",
26
+ "components",
27
+ "diffComponent",
28
+ "initialValue",
29
+ "deprecated"
30
+ ], OWN_PROPS_NAME = "_internal_ownProps", ALL_FIELDS_GROUP_NAME = "all-fields";
13
31
  function lazyGetter(target, key, getter, config = {}) {
14
32
  return Object.defineProperty(target, key, {
15
33
  configurable: !0,
@@ -80,7 +98,7 @@ const OVERRIDABLE_FIELDS$f = [...DEFAULT_OVERRIDEABLE_FIELDS], ANY_CORE = {
80
98
  const parsed = Object.assign(pick(ARRAY_CORE, OVERRIDABLE_FIELDS$e), subTypeDef, {
81
99
  type: ARRAY_CORE
82
100
  });
83
- return lazyGetter(parsed, "of", () => subTypeDef.of.map((ofTypeDef) => createMemberType(ofTypeDef))), lazyGetter(parsed, OWN_PROPS_NAME, () => ({ ...subTypeDef, of: parsed.of }), {
101
+ return lazyGetter(parsed, "of", () => subTypeDef.of.map((ofTypeDef) => createMemberType.cached(ofTypeDef))), lazyGetter(parsed, OWN_PROPS_NAME, () => ({ ...subTypeDef, of: parsed.of }), {
84
102
  enumerable: !1,
85
103
  writable: !1
86
104
  }), subtype(parsed);
@@ -253,7 +271,7 @@ const DEFAULT_LINK_ANNOTATION = {
253
271
  type: "url",
254
272
  title: "Link",
255
273
  description: "A valid web, email, phone, or relative link.",
256
- validation: (Rule) => Rule.uri({
274
+ validation: (Rule3) => Rule3.uri({
257
275
  scheme: ["http", "https", "tel", "mailto"],
258
276
  allowRelative: !0
259
277
  })
@@ -366,13 +384,7 @@ const DEFAULT_LINK_ANNOTATION = {
366
384
  ), ownProps = { ...rest, options }, parsed = Object.assign(pick(BLOCK_CORE, INHERITED_FIELDS$1), ownProps, {
367
385
  type: BLOCK_CORE
368
386
  });
369
- return lazyGetter(parsed, "fields", () => fields.map((fieldDef) => {
370
- const { name, ...type } = fieldDef;
371
- return {
372
- name,
373
- type: extendMember(type)
374
- };
375
- })), lazyGetter(parsed, "preview", createPreviewGetter(subTypeDef)), lazyGetter(
387
+ return lazyGetter(parsed, "fields", () => fields.map((fieldDef) => extendMember.cachedField(fieldDef))), lazyGetter(parsed, "preview", createPreviewGetter(subTypeDef)), lazyGetter(
376
388
  parsed,
377
389
  OWN_PROPS_NAME,
378
390
  () => ({
@@ -470,13 +482,7 @@ const INHERITED_FIELDS = [
470
482
  const options = { ...subTypeDef.options || DEFAULT_OPTIONS$2 }, { annotations = [], marks = [] } = subTypeDef, fields = [MARKS_FIELD, TEXT_FIELD], ownProps = { ...subTypeDef, options }, parsed = Object.assign(pick(SPAN_CORE, INHERITED_FIELDS), ownProps, {
471
483
  type: SPAN_CORE
472
484
  });
473
- return lazyGetter(parsed, "fields", () => fields.map((fieldDef) => {
474
- const { name, ...type } = fieldDef;
475
- return {
476
- name,
477
- type: extendMember(type)
478
- };
479
- })), lazyGetter(parsed, "annotations", () => annotations.map(extendMember)), lazyGetter(parsed, "marks", () => marks.map(extendMember)), lazyGetter(parsed, "preview", createPreviewGetter(subTypeDef)), lazyGetter(
485
+ return lazyGetter(parsed, "fields", () => fields.map((fieldDef) => extendMember.cachedField(fieldDef))), lazyGetter(parsed, "annotations", () => annotations.map(extendMember)), lazyGetter(parsed, "marks", () => marks.map(extendMember)), lazyGetter(parsed, "preview", createPreviewGetter(subTypeDef)), lazyGetter(
480
486
  parsed,
481
487
  OWN_PROPS_NAME,
482
488
  () => ({
@@ -539,7 +545,91 @@ const OVERRIDABLE_FIELDS$d = [...DEFAULT_OVERRIDEABLE_FIELDS], BOOLEAN_CORE = {
539
545
  };
540
546
  }
541
547
  }
542
- }, REF_FIELD$2 = {
548
+ }, DEFAULT_MAX_FIELD_DEPTH = 5, stringFieldsSymbols = {}, getStringFieldSymbol = (maxDepth) => (stringFieldsSymbols[maxDepth] || (stringFieldsSymbols[maxDepth] = /* @__PURE__ */ Symbol(`__cachedStringFields_${maxDepth}`)), stringFieldsSymbols[maxDepth]), isReference = (type) => type.type && type.type.name === "reference", portableTextFields = ["style", "list"], isPortableTextBlock = (type) => type.name === "block" || type.type && isPortableTextBlock(type.type), isPortableTextArray = (type) => type.jsonType === "array" && Array.isArray(type.of) && type.of.some(isPortableTextBlock);
549
+ function reduceType(type, reducer, acc, path = [], maxDepth) {
550
+ if (maxDepth < 0)
551
+ return acc;
552
+ const accumulator = reducer(acc, type, path);
553
+ return type.jsonType === "array" && Array.isArray(type.of) ? reduceArray(type, reducer, accumulator, path, maxDepth) : type.jsonType === "object" && Array.isArray(type.fields) && !isReference(type) ? reduceObject(type, reducer, accumulator, path, maxDepth) : accumulator;
554
+ }
555
+ function reduceArray(arrayType, reducer, accumulator, path, maxDepth) {
556
+ return arrayType.of.reduce(
557
+ (acc, ofType) => reduceType(ofType, reducer, acc, path, maxDepth - 1),
558
+ accumulator
559
+ );
560
+ }
561
+ function reduceObject(objectType, reducer, accumulator, path, maxDepth) {
562
+ const isPtBlock = isPortableTextBlock(objectType);
563
+ return objectType.fields.reduce((acc, field) => {
564
+ if (isPtBlock && portableTextFields.includes(field.name))
565
+ return acc;
566
+ const segment = [field.name].concat(field.type.jsonType === "array" ? [[]] : []);
567
+ return reduceType(field.type, reducer, acc, path.concat(segment), maxDepth - 1);
568
+ }, accumulator);
569
+ }
570
+ const BASE_WEIGHTS = [
571
+ { weight: 1, path: ["_id"] },
572
+ { weight: 1, path: ["_type"] }
573
+ ], PREVIEW_FIELD_WEIGHT_MAP = {
574
+ title: 10,
575
+ subtitle: 5,
576
+ description: 1.5
577
+ };
578
+ function deriveFromPreview(type, maxDepth) {
579
+ const select = type?.preview?.select;
580
+ if (!select)
581
+ return [];
582
+ const fields = [];
583
+ for (const fieldName of Object.keys(select)) {
584
+ if (!(fieldName in PREVIEW_FIELD_WEIGHT_MAP))
585
+ continue;
586
+ const path = select[fieldName].split(".");
587
+ maxDepth > -1 && path.length - 1 > maxDepth || fields.push({
588
+ weight: PREVIEW_FIELD_WEIGHT_MAP[fieldName],
589
+ path
590
+ });
591
+ }
592
+ return fields;
593
+ }
594
+ function getCachedStringFieldPaths(type, maxDepth) {
595
+ const symbol = getStringFieldSymbol(maxDepth);
596
+ return type[symbol] || (type[symbol] = uniqBy(
597
+ [
598
+ ...BASE_WEIGHTS,
599
+ ...deriveFromPreview(type, maxDepth),
600
+ ...getStringFieldPaths(type, maxDepth).map((path) => ({ weight: 1, path })),
601
+ ...getPortableTextFieldPaths(type, maxDepth).map((path) => ({
602
+ weight: 1,
603
+ path,
604
+ mapWith: "pt::text"
605
+ }))
606
+ ],
607
+ (spec) => spec.path.join(".")
608
+ )), type[symbol];
609
+ }
610
+ function getCachedBaseFieldPaths(type, maxDepth) {
611
+ const symbol = getStringFieldSymbol(maxDepth);
612
+ return type[symbol] || (type[symbol] = uniqBy(
613
+ [...BASE_WEIGHTS, ...deriveFromPreview(type, maxDepth)],
614
+ (spec) => spec.path.join(".")
615
+ )), type[symbol];
616
+ }
617
+ function getStringFieldPaths(type, maxDepth) {
618
+ return reduceType(type, (accumulator, childType, path) => childType.jsonType === "string" ? [...accumulator, path] : accumulator, [], [], maxDepth);
619
+ }
620
+ function getPortableTextFieldPaths(type, maxDepth) {
621
+ return reduceType(type, (accumulator, childType, path) => isPortableTextArray(childType) ? [...accumulator, path] : accumulator, [], [], maxDepth);
622
+ }
623
+ function resolveSearchConfigForBaseFieldPaths(type, maxDepth) {
624
+ return getCachedBaseFieldPaths(type, normalizeMaxDepth(maxDepth));
625
+ }
626
+ function resolveSearchConfig(type, maxDepth) {
627
+ return getCachedStringFieldPaths(type, normalizeMaxDepth(maxDepth));
628
+ }
629
+ function normalizeMaxDepth(maxDepth) {
630
+ return !isFinite(maxDepth) || maxDepth < 1 || maxDepth > DEFAULT_MAX_FIELD_DEPTH ? DEFAULT_MAX_FIELD_DEPTH - 1 : maxDepth - 1;
631
+ }
632
+ const REF_FIELD$2 = {
543
633
  name: "_ref",
544
634
  title: "Referenced document ID",
545
635
  type: "string"
@@ -590,13 +680,7 @@ const CrossDatasetReferenceType = {
590
680
  type: CROSS_DATASET_REFERENCE_CORE
591
681
  }
592
682
  );
593
- return lazyGetter(parsed, "fields", () => REFERENCE_FIELDS$2.map((fieldDef) => {
594
- const { name, ...type } = fieldDef;
595
- return {
596
- name,
597
- type: createMemberType(type)
598
- };
599
- })), lazyGetter(parsed, "to", () => arrify(subTypeDef.to).map((toType) => ({
683
+ return lazyGetter(parsed, "fields", () => REFERENCE_FIELDS$2.map((fieldDef) => createMemberType.cachedField(fieldDef))), lazyGetter(parsed, "to", () => arrify(subTypeDef.to).map((toType) => ({
600
684
  ...toType,
601
685
  // eslint-disable-next-line camelcase
602
686
  __experimental_search: resolveSearchConfigForBaseFieldPaths(toType)
@@ -743,17 +827,9 @@ const OVERRIDABLE_FIELDS$9 = [
743
827
  title: subTypeDef.title || (subTypeDef.name ? startCase(subTypeDef.name) : "Object"),
744
828
  options,
745
829
  orderings: subTypeDef.orderings || guessOrderingConfig(subTypeDef),
746
- fields: subTypeDef.fields.map((fieldDef) => {
747
- const { name, fieldset, group, ...rest } = fieldDef;
748
- return lazyGetter({
749
- name,
750
- group,
751
- fieldset
752
- }, "type", () => createMemberType({
753
- ...rest,
754
- title: fieldDef.title || startCase(name)
755
- }));
756
- })
830
+ fields: subTypeDef.fields.map(
831
+ (fieldDef) => createMemberType.cachedObjectField(fieldDef)
832
+ )
757
833
  }, parsed = Object.assign(pick(this.get(), OVERRIDABLE_FIELDS$9), ownProps, {
758
834
  type: this.get()
759
835
  });
@@ -844,7 +920,11 @@ function createFieldsGroups(typeDef, fields) {
844
920
  );
845
921
  currentGroup.fields.push(field);
846
922
  });
847
- }), flatMap(groupsByName).filter((group) => group.fields.length > 0);
923
+ }), flatMap(groupsByName).filter(
924
+ // All fields group is added by default in structure.
925
+ // To pass the properties from the schema to the form state, we need to include it in the list of groups.
926
+ (group) => group.fields.length > 0 || group.name === ALL_FIELDS_GROUP_NAME
927
+ );
848
928
  }
849
929
  const DOCUMENT_CORE = {
850
930
  name: "document",
@@ -867,7 +947,7 @@ lazyGetter(
867
947
  OWN_PROPS_NAME,
868
948
  () => ({
869
949
  ...EMAIL_CORE,
870
- validation: (Rule) => Rule.email()
950
+ validation: (Rule3) => Rule3.email()
871
951
  }),
872
952
  { enumerable: !1 }
873
953
  );
@@ -1006,13 +1086,7 @@ const GlobalDocumentReferenceType = {
1006
1086
  type: GLOBAL_DOCUMENT_REFERENCE_CORE
1007
1087
  }
1008
1088
  );
1009
- return lazyGetter(parsed, "fields", () => REFERENCE_FIELDS$1.map((fieldDef) => {
1010
- const { name, ...type } = fieldDef;
1011
- return {
1012
- name,
1013
- type: createMemberType(type)
1014
- };
1015
- })), lazyGetter(parsed, "to", () => arrify(subTypeDef.to).map((toType) => ({
1089
+ return lazyGetter(parsed, "fields", () => REFERENCE_FIELDS$1.map((fieldDef) => createMemberType.cachedField(fieldDef))), lazyGetter(parsed, "to", () => arrify(subTypeDef.to).map((toType) => ({
1016
1090
  ...toType
1017
1091
  }))), lazyGetter(parsed, "title", () => subTypeDef.title || buildTitle$1(parsed)), lazyGetter(
1018
1092
  parsed,
@@ -1189,13 +1263,7 @@ const ReferenceType = {
1189
1263
  const parsed = Object.assign(pick(REFERENCE_CORE, OVERRIDABLE_FIELDS$3), subTypeDef, {
1190
1264
  type: REFERENCE_CORE
1191
1265
  });
1192
- return lazyGetter(parsed, "fields", () => REFERENCE_FIELDS.map((fieldDef) => {
1193
- const { name, ...type } = fieldDef;
1194
- return {
1195
- name,
1196
- type: createMemberType(type)
1197
- };
1198
- })), lazyGetter(parsed, "fieldsets", () => createFieldsets(subTypeDef, parsed.fields)), lazyGetter(parsed, "to", () => arrify(subTypeDef.to).map((toType) => createMemberType(toType))), lazyGetter(parsed, "title", () => subTypeDef.title || buildTitle(parsed)), lazyGetter(
1266
+ return lazyGetter(parsed, "fields", () => REFERENCE_FIELDS.map((fieldDef) => createMemberType.cachedField(fieldDef))), lazyGetter(parsed, "fieldsets", () => createFieldsets(subTypeDef, parsed.fields)), lazyGetter(parsed, "to", () => arrify(subTypeDef.to).map((toType) => createMemberType(toType))), lazyGetter(parsed, "title", () => subTypeDef.title || buildTitle(parsed)), lazyGetter(
1199
1267
  parsed,
1200
1268
  OWN_PROPS_NAME,
1201
1269
  () => ({
@@ -1347,7 +1415,38 @@ function compileRegistry(schemaDef) {
1347
1415
  if (acc[def.name])
1348
1416
  throw new Error(`Duplicate type name added to schema: ${def.name}`);
1349
1417
  return acc[def.name] = def, acc;
1350
- }, {});
1418
+ }, {}), memberCache = /* @__PURE__ */ new Map(), fieldCache = /* @__PURE__ */ new Map(), objectFieldCache = /* @__PURE__ */ new Map(), extendHelper = Object.assign(extendMember, {
1419
+ cached(def) {
1420
+ let member = memberCache.get(def);
1421
+ return member || (member = extendMember(def), memberCache.set(def, member)), member;
1422
+ },
1423
+ cachedField(fieldDef) {
1424
+ let field = fieldCache.get(fieldDef);
1425
+ if (!field) {
1426
+ const { name, ...type } = fieldDef;
1427
+ field = {
1428
+ name,
1429
+ type: extendMember(type)
1430
+ }, fieldCache.set(fieldDef, field);
1431
+ }
1432
+ return field;
1433
+ },
1434
+ cachedObjectField(fieldDef) {
1435
+ let field = objectFieldCache.get(fieldDef);
1436
+ if (!field) {
1437
+ const { name, fieldset, group, ...rest } = fieldDef;
1438
+ field = {
1439
+ name,
1440
+ group,
1441
+ fieldset
1442
+ }, lazyGetter(field, "type", () => extendMember({
1443
+ ...rest,
1444
+ title: fieldDef.title || startCase(name)
1445
+ })), objectFieldCache.set(fieldDef, field);
1446
+ }
1447
+ return field;
1448
+ }
1449
+ });
1351
1450
  return schemaDef.types.forEach(add), {
1352
1451
  registry,
1353
1452
  localTypeNames
@@ -1360,13 +1459,13 @@ function compileRegistry(schemaDef) {
1360
1459
  }
1361
1460
  }
1362
1461
  function extendMember(memberDef) {
1363
- return ensure(memberDef.type), registry[memberDef.type].extend(memberDef, extendMember).get();
1462
+ return ensure(memberDef.type), registry[memberDef.type].extend(memberDef, extendHelper).get();
1364
1463
  }
1365
1464
  function add(typeDef) {
1366
1465
  ensure(typeDef.type), !registry[typeDef.name] && (localTypeNames.push(typeDef.name), registry[typeDef.name] = registry[typeDef.type].extend(typeDef, extendMember));
1367
1466
  }
1368
1467
  }
1369
- let Schema$1 = class Schema {
1468
+ class Schema {
1370
1469
  _original;
1371
1470
  _registry;
1372
1471
  #localTypeNames;
@@ -1399,8 +1498,8 @@ let Schema$1 = class Schema {
1399
1498
  getLocalTypeNames() {
1400
1499
  return this.#localTypeNames;
1401
1500
  }
1402
- };
1403
- class DeprecatedDefaultSchema extends Schema$1 {
1501
+ }
1502
+ class DeprecatedDefaultSchema extends Schema {
1404
1503
  static compile(schemaDef) {
1405
1504
  return new DeprecatedDefaultSchema(schemaDef);
1406
1505
  }
@@ -1412,9 +1511,216 @@ class DeprecatedDefaultSchema extends Schema$1 {
1412
1511
  console.warn(stack);
1413
1512
  }
1414
1513
  }
1415
- const Schema2 = Schema$1;
1514
+ const FIELD_REF = /* @__PURE__ */ Symbol("FIELD_REF"), ruleConstraintTypes = [
1515
+ "Array",
1516
+ "Boolean",
1517
+ "Date",
1518
+ "Number",
1519
+ "Object",
1520
+ "String"
1521
+ ], Rule = class Rule2 {
1522
+ static FIELD_REF = FIELD_REF;
1523
+ static array = (def) => new Rule2(def).type("Array");
1524
+ static object = (def) => new Rule2(def).type("Object");
1525
+ static string = (def) => new Rule2(def).type("String");
1526
+ static number = (def) => new Rule2(def).type("Number");
1527
+ static boolean = (def) => new Rule2(def).type("Boolean");
1528
+ static dateTime = (def) => new Rule2(def).type("Date");
1529
+ static valueOfField = (path) => ({
1530
+ type: FIELD_REF,
1531
+ path
1532
+ });
1533
+ _type = void 0;
1534
+ _level = void 0;
1535
+ _required = void 0;
1536
+ _typeDef = void 0;
1537
+ _message = void 0;
1538
+ _rules = [];
1539
+ _fieldRules = void 0;
1540
+ constructor(typeDef) {
1541
+ this._typeDef = typeDef, this.reset();
1542
+ }
1543
+ _mergeRequired(next) {
1544
+ if (this._required === "required" || next._required === "required") return "required";
1545
+ if (this._required === "optional" || next._required === "optional") return "optional";
1546
+ }
1547
+ // Alias to static method, since we often have access to an _instance_ of a rule but not the actual Rule class
1548
+ valueOfField = Rule2.valueOfField.bind(Rule2);
1549
+ error(message) {
1550
+ const rule = this.clone();
1551
+ return rule._level = "error", rule._message = message || void 0, rule;
1552
+ }
1553
+ warning(message) {
1554
+ const rule = this.clone();
1555
+ return rule._level = "warning", rule._message = message || void 0, rule;
1556
+ }
1557
+ info(message) {
1558
+ const rule = this.clone();
1559
+ return rule._level = "info", rule._message = message || void 0, rule;
1560
+ }
1561
+ reset() {
1562
+ return this._type = this._type || void 0, this._rules = (this._rules || []).filter((rule) => rule.flag === "type"), this._message = void 0, this._required = void 0, this._level = "error", this._fieldRules = void 0, this;
1563
+ }
1564
+ isRequired() {
1565
+ return this._required === "required";
1566
+ }
1567
+ clone() {
1568
+ const rule = new Rule2();
1569
+ return rule._type = this._type, rule._message = this._message, rule._required = this._required, rule._rules = cloneDeep(this._rules), rule._level = this._level, rule._fieldRules = this._fieldRules, rule._typeDef = this._typeDef, rule;
1570
+ }
1571
+ cloneWithRules(rules) {
1572
+ const rule = this.clone(), newRules = /* @__PURE__ */ new Set();
1573
+ return rules.forEach((curr) => {
1574
+ curr.flag === "type" && (rule._type = curr.constraint), newRules.add(curr.flag);
1575
+ }), rule._rules = rule._rules.filter((curr) => {
1576
+ const disallowDuplicate = ["type", "uri", "email"].includes(curr.flag), isDuplicate = newRules.has(curr.flag);
1577
+ return !(disallowDuplicate && isDuplicate);
1578
+ }).concat(rules), rule;
1579
+ }
1580
+ merge(rule) {
1581
+ if (this._type && rule._type && this._type !== rule._type)
1582
+ throw new Error("merge() failed: conflicting types");
1583
+ const newRule = this.cloneWithRules(rule._rules);
1584
+ return newRule._type = this._type || rule._type, newRule._message = this._message || rule._message, newRule._required = this._mergeRequired(rule), newRule._level = this._level === "error" ? rule._level : this._level, newRule;
1585
+ }
1586
+ // Validation flag setters
1587
+ type(targetType) {
1588
+ const type = `${targetType.slice(0, 1).toUpperCase()}${targetType.slice(1)}`;
1589
+ if (!ruleConstraintTypes.includes(type))
1590
+ throw new Error(`Unknown type "${targetType}"`);
1591
+ const rule = this.cloneWithRules([{ flag: "type", constraint: type }]);
1592
+ return rule._type = type, rule;
1593
+ }
1594
+ all(children) {
1595
+ return this.cloneWithRules([{ flag: "all", constraint: children }]);
1596
+ }
1597
+ either(children) {
1598
+ return this.cloneWithRules([{ flag: "either", constraint: children }]);
1599
+ }
1600
+ // Shared rules
1601
+ optional() {
1602
+ const rule = this.cloneWithRules([{ flag: "presence", constraint: "optional" }]);
1603
+ return rule._required = "optional", rule;
1604
+ }
1605
+ required() {
1606
+ const rule = this.cloneWithRules([{ flag: "presence", constraint: "required" }]);
1607
+ return rule._required = "required", rule;
1608
+ }
1609
+ custom(fn, options = {}) {
1610
+ return options.bypassConcurrencyLimit && Object.assign(fn, { bypassConcurrencyLimit: !0 }), this.cloneWithRules([{ flag: "custom", constraint: fn }]);
1611
+ }
1612
+ min(len) {
1613
+ return this.cloneWithRules([{ flag: "min", constraint: len }]);
1614
+ }
1615
+ max(len) {
1616
+ return this.cloneWithRules([{ flag: "max", constraint: len }]);
1617
+ }
1618
+ length(len) {
1619
+ return this.cloneWithRules([{ flag: "length", constraint: len }]);
1620
+ }
1621
+ valid(value) {
1622
+ const values = Array.isArray(value) ? value : [value];
1623
+ return this.cloneWithRules([{ flag: "valid", constraint: values }]);
1624
+ }
1625
+ // Numbers only
1626
+ integer() {
1627
+ return this.cloneWithRules([{ flag: "integer" }]);
1628
+ }
1629
+ precision(limit) {
1630
+ return this.cloneWithRules([{ flag: "precision", constraint: limit }]);
1631
+ }
1632
+ positive() {
1633
+ return this.cloneWithRules([{ flag: "min", constraint: 0 }]);
1634
+ }
1635
+ negative() {
1636
+ return this.cloneWithRules([{ flag: "lessThan", constraint: 0 }]);
1637
+ }
1638
+ greaterThan(num) {
1639
+ return this.cloneWithRules([{ flag: "greaterThan", constraint: num }]);
1640
+ }
1641
+ lessThan(num) {
1642
+ return this.cloneWithRules([{ flag: "lessThan", constraint: num }]);
1643
+ }
1644
+ // String only
1645
+ uppercase() {
1646
+ return this.cloneWithRules([{ flag: "stringCasing", constraint: "uppercase" }]);
1647
+ }
1648
+ lowercase() {
1649
+ return this.cloneWithRules([{ flag: "stringCasing", constraint: "lowercase" }]);
1650
+ }
1651
+ regex(pattern, a, b) {
1652
+ const name = typeof a == "string" ? a : a?.name ?? b?.name, invert = typeof a == "string" ? !1 : a?.invert ?? b?.invert, constraint = {
1653
+ pattern,
1654
+ name,
1655
+ invert: invert || !1
1656
+ };
1657
+ return this.cloneWithRules([{ flag: "regex", constraint }]);
1658
+ }
1659
+ email() {
1660
+ return this.cloneWithRules([{ flag: "email" }]);
1661
+ }
1662
+ uri(opts) {
1663
+ const optsScheme = opts?.scheme || ["http", "https"], schemes = Array.isArray(optsScheme) ? optsScheme : [optsScheme];
1664
+ if (!schemes.length)
1665
+ throw new Error("scheme must have at least 1 scheme specified");
1666
+ const constraint = {
1667
+ options: {
1668
+ scheme: schemes.map((scheme) => {
1669
+ if (!(scheme instanceof RegExp) && typeof scheme != "string")
1670
+ throw new Error("scheme must be a RegExp or a String");
1671
+ return typeof scheme == "string" ? new RegExp(`^${escapeRegex(scheme)}$`) : scheme;
1672
+ }),
1673
+ allowRelative: opts?.allowRelative || !1,
1674
+ relativeOnly: opts?.relativeOnly || !1,
1675
+ allowCredentials: opts?.allowCredentials || !1
1676
+ }
1677
+ };
1678
+ return this.cloneWithRules([{ flag: "uri", constraint }]);
1679
+ }
1680
+ // Array only
1681
+ unique() {
1682
+ return this.cloneWithRules([{ flag: "unique" }]);
1683
+ }
1684
+ // Objects only
1685
+ reference() {
1686
+ return this.cloneWithRules([{ flag: "reference" }]);
1687
+ }
1688
+ fields(rules) {
1689
+ if (this._type !== "Object")
1690
+ throw new Error("fields() can only be called on an object type");
1691
+ const rule = this.cloneWithRules([]);
1692
+ return rule._fieldRules = rules, rule;
1693
+ }
1694
+ assetRequired() {
1695
+ const base = getBaseType(this._typeDef);
1696
+ let assetType;
1697
+ return base && ["image", "file"].includes(base.name) ? assetType = base.name === "image" ? "image" : "file" : assetType = "asset", this.cloneWithRules([{ flag: "assetRequired", constraint: { assetType } }]);
1698
+ }
1699
+ media(fn) {
1700
+ return this.cloneWithRules([{ flag: "media", constraint: fn }]);
1701
+ }
1702
+ /**
1703
+ * The validate method is not implemented in the base Rule class.
1704
+ * It should be implemented by extending this class or injecting validation logic.
1705
+ */
1706
+ async validate(value, options) {
1707
+ throw new Error("validate() method must be implemented by extending Rule class");
1708
+ }
1709
+ };
1710
+ function getBaseType(type) {
1711
+ return type && type.type ? getBaseType(type.type) : type;
1712
+ }
1713
+ function escapeRegex(string) {
1714
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1715
+ }
1416
1716
  export {
1417
- Schema2 as Schema,
1418
- DeprecatedDefaultSchema as default
1717
+ ALL_FIELDS_GROUP_NAME,
1718
+ DEFAULT_MAX_FIELD_DEPTH,
1719
+ DeprecatedDefaultSchema,
1720
+ OWN_PROPS_NAME,
1721
+ Rule,
1722
+ Schema,
1723
+ resolveSearchConfig,
1724
+ resolveSearchConfigForBaseFieldPaths
1419
1725
  };
1420
- //# sourceMappingURL=index.mjs.map
1726
+ //# sourceMappingURL=Rule.js.map