@sanity/schema 5.30.1-next.8 → 5.31.0-next.10

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.
@@ -1,3 +1,4 @@
1
+ import cloneDeep from "lodash-es/cloneDeep.js";
1
2
  import startCase from "lodash-es/startCase.js";
2
3
  import omit from "lodash-es/omit.js";
3
4
  import pick from "lodash-es/pick.js";
@@ -11,7 +12,212 @@ import castArray from "lodash-es/castArray.js";
11
12
  import flatMap from "lodash-es/flatMap.js";
12
13
  import isPlainObject from "lodash-es/isPlainObject.js";
13
14
  import toPath from "lodash-es/toPath.js";
14
- import cloneDeep from "lodash-es/cloneDeep.js";
15
+ const FIELD_REF = /* @__PURE__ */ Symbol.for("@sanity/schema/field-ref"), ruleConstraintTypes = [
16
+ "Array",
17
+ "Boolean",
18
+ "Date",
19
+ "Number",
20
+ "Object",
21
+ "String"
22
+ ], Rule = class Rule2 {
23
+ static FIELD_REF = FIELD_REF;
24
+ static array = (def) => new Rule2(def).type("Array");
25
+ static object = (def) => new Rule2(def).type("Object");
26
+ static string = (def) => new Rule2(def).type("String");
27
+ static number = (def) => new Rule2(def).type("Number");
28
+ static boolean = (def) => new Rule2(def).type("Boolean");
29
+ static dateTime = (def) => new Rule2(def).type("Date");
30
+ static valueOfField = (path) => ({
31
+ type: FIELD_REF,
32
+ path
33
+ });
34
+ _type = void 0;
35
+ _level = void 0;
36
+ _required = void 0;
37
+ _typeDef = void 0;
38
+ _message = void 0;
39
+ _rules = [];
40
+ _fieldRules = void 0;
41
+ constructor(typeDef) {
42
+ this._typeDef = typeDef, this.reset();
43
+ }
44
+ _mergeRequired(next) {
45
+ if (this._required === "required" || next._required === "required") return "required";
46
+ if (this._required === "optional" || next._required === "optional") return "optional";
47
+ }
48
+ // Alias to static method, since we often have access to an _instance_ of a rule but not the actual Rule class
49
+ valueOfField = Rule2.valueOfField.bind(Rule2);
50
+ error(message) {
51
+ const rule = this.clone();
52
+ return rule._level = "error", rule._message = message || void 0, rule;
53
+ }
54
+ warning(message) {
55
+ const rule = this.clone();
56
+ return rule._level = "warning", rule._message = message || void 0, rule;
57
+ }
58
+ info(message) {
59
+ const rule = this.clone();
60
+ return rule._level = "info", rule._message = message || void 0, rule;
61
+ }
62
+ reset() {
63
+ 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;
64
+ }
65
+ isRequired() {
66
+ return this._required === "required";
67
+ }
68
+ clone() {
69
+ const rule = new Rule2();
70
+ 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;
71
+ }
72
+ cloneWithRules(rules) {
73
+ const rule = this.clone(), newRules = /* @__PURE__ */ new Set();
74
+ return rules.forEach((curr) => {
75
+ curr.flag === "type" && (rule._type = curr.constraint), newRules.add(curr.flag);
76
+ }), rule._rules = rule._rules.filter((curr) => {
77
+ const disallowDuplicate = ["type", "uri", "email"].includes(curr.flag), isDuplicate = newRules.has(curr.flag);
78
+ return !(disallowDuplicate && isDuplicate);
79
+ }).concat(rules), rule;
80
+ }
81
+ merge(rule) {
82
+ if (this._type && rule._type && this._type !== rule._type)
83
+ throw new Error("merge() failed: conflicting types");
84
+ const newRule = this.cloneWithRules(rule._rules);
85
+ 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;
86
+ }
87
+ // Validation flag setters
88
+ type(targetType) {
89
+ const type = `${targetType.slice(0, 1).toUpperCase()}${targetType.slice(1)}`;
90
+ if (!ruleConstraintTypes.includes(type))
91
+ throw new Error(`Unknown type "${targetType}"`);
92
+ const rule = this.cloneWithRules([{ flag: "type", constraint: type }]);
93
+ return rule._type = type, rule;
94
+ }
95
+ all(children) {
96
+ return this.cloneWithRules([{ flag: "all", constraint: children }]);
97
+ }
98
+ either(children) {
99
+ return this.cloneWithRules([{ flag: "either", constraint: children }]);
100
+ }
101
+ // Shared rules
102
+ optional() {
103
+ const rule = this.cloneWithRules([{ flag: "presence", constraint: "optional" }]);
104
+ return rule._required = "optional", rule;
105
+ }
106
+ skip() {
107
+ const rule = this.clone();
108
+ return rule._rules = [], rule._required = "optional", rule._message = void 0, rule._level = "error", rule._fieldRules = void 0, rule;
109
+ }
110
+ required() {
111
+ const rule = this.cloneWithRules([{ flag: "presence", constraint: "required" }]);
112
+ return rule._required = "required", rule;
113
+ }
114
+ custom(fn, options = {}) {
115
+ return options.bypassConcurrencyLimit && Object.assign(fn, { bypassConcurrencyLimit: !0 }), this.cloneWithRules([{ flag: "custom", constraint: fn }]);
116
+ }
117
+ min(len) {
118
+ return this.cloneWithRules([{ flag: "min", constraint: len }]);
119
+ }
120
+ max(len) {
121
+ return this.cloneWithRules([{ flag: "max", constraint: len }]);
122
+ }
123
+ length(len) {
124
+ return this.cloneWithRules([{ flag: "length", constraint: len }]);
125
+ }
126
+ valid(value) {
127
+ const values = Array.isArray(value) ? value : [value];
128
+ return this.cloneWithRules([{ flag: "valid", constraint: values }]);
129
+ }
130
+ // Numbers only
131
+ integer() {
132
+ return this.cloneWithRules([{ flag: "integer" }]);
133
+ }
134
+ precision(limit) {
135
+ return this.cloneWithRules([{ flag: "precision", constraint: limit }]);
136
+ }
137
+ positive() {
138
+ return this.cloneWithRules([{ flag: "min", constraint: 0 }]);
139
+ }
140
+ negative() {
141
+ return this.cloneWithRules([{ flag: "lessThan", constraint: 0 }]);
142
+ }
143
+ greaterThan(num) {
144
+ return this.cloneWithRules([{ flag: "greaterThan", constraint: num }]);
145
+ }
146
+ lessThan(num) {
147
+ return this.cloneWithRules([{ flag: "lessThan", constraint: num }]);
148
+ }
149
+ // String only
150
+ uppercase() {
151
+ return this.cloneWithRules([{ flag: "stringCasing", constraint: "uppercase" }]);
152
+ }
153
+ lowercase() {
154
+ return this.cloneWithRules([{ flag: "stringCasing", constraint: "lowercase" }]);
155
+ }
156
+ regex(pattern, a, b) {
157
+ const name = typeof a == "string" ? a : a?.name ?? b?.name, invert = typeof a == "string" ? !1 : a?.invert ?? b?.invert, constraint = {
158
+ pattern,
159
+ name,
160
+ invert: invert || !1
161
+ };
162
+ return this.cloneWithRules([{ flag: "regex", constraint }]);
163
+ }
164
+ email() {
165
+ return this.cloneWithRules([{ flag: "email" }]);
166
+ }
167
+ uri(opts) {
168
+ const optsScheme = opts?.scheme || ["http", "https"], schemes = Array.isArray(optsScheme) ? optsScheme : [optsScheme];
169
+ if (!schemes.length)
170
+ throw new Error("scheme must have at least 1 scheme specified");
171
+ const constraint = {
172
+ options: {
173
+ scheme: schemes.map((scheme) => {
174
+ if (!(scheme instanceof RegExp) && typeof scheme != "string")
175
+ throw new Error("scheme must be a RegExp or a String");
176
+ return typeof scheme == "string" ? new RegExp(`^${escapeRegex(scheme)}$`) : scheme;
177
+ }),
178
+ allowRelative: opts?.allowRelative || !1,
179
+ relativeOnly: opts?.relativeOnly || !1,
180
+ allowCredentials: opts?.allowCredentials || !1
181
+ }
182
+ };
183
+ return this.cloneWithRules([{ flag: "uri", constraint }]);
184
+ }
185
+ // Array only
186
+ unique() {
187
+ return this.cloneWithRules([{ flag: "unique" }]);
188
+ }
189
+ // Objects only
190
+ reference() {
191
+ return this.cloneWithRules([{ flag: "reference" }]);
192
+ }
193
+ fields(rules) {
194
+ if (this._type !== "Object")
195
+ throw new Error("fields() can only be called on an object type");
196
+ const rule = this.cloneWithRules([]);
197
+ return rule._fieldRules = rules, rule;
198
+ }
199
+ assetRequired() {
200
+ const base = getBaseType(this._typeDef);
201
+ let assetType;
202
+ return base && ["image", "file"].includes(base.name) ? assetType = base.name === "image" ? "image" : "file" : assetType = "asset", this.cloneWithRules([{ flag: "assetRequired", constraint: { assetType } }]);
203
+ }
204
+ media(fn) {
205
+ return this.cloneWithRules([{ flag: "media", constraint: fn }]);
206
+ }
207
+ /**
208
+ * The validate method is not implemented in the base Rule class.
209
+ * It should be implemented by extending this class or injecting validation logic.
210
+ */
211
+ async validate(value, options) {
212
+ throw new Error("validate() method must be implemented by extending Rule class");
213
+ }
214
+ };
215
+ function getBaseType(type) {
216
+ return type && type.type ? getBaseType(type.type) : type;
217
+ }
218
+ function escapeRegex(string) {
219
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
220
+ }
15
221
  const DEFAULT_OVERRIDEABLE_FIELDS = [
16
222
  "jsonType",
17
223
  "type",
@@ -27,7 +233,90 @@ const DEFAULT_OVERRIDEABLE_FIELDS = [
27
233
  "diffComponent",
28
234
  "initialValue",
29
235
  "deprecated"
30
- ], OWN_PROPS_NAME = "_internal_ownProps", ALL_FIELDS_GROUP_NAME = "all-fields";
236
+ ], OWN_PROPS_NAME = "_internal_ownProps", ALL_FIELDS_GROUP_NAME = "all-fields", 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);
237
+ function reduceType(type, reducer, acc, path = [], maxDepth) {
238
+ if (maxDepth < 0)
239
+ return acc;
240
+ const accumulator = reducer(acc, type, path);
241
+ 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;
242
+ }
243
+ function reduceArray(arrayType, reducer, accumulator, path, maxDepth) {
244
+ return arrayType.of.reduce(
245
+ (acc, ofType) => reduceType(ofType, reducer, acc, path, maxDepth - 1),
246
+ accumulator
247
+ );
248
+ }
249
+ function reduceObject(objectType, reducer, accumulator, path, maxDepth) {
250
+ const isPtBlock = isPortableTextBlock(objectType);
251
+ return objectType.fields.reduce((acc, field) => {
252
+ if (isPtBlock && portableTextFields.includes(field.name))
253
+ return acc;
254
+ const segment = [field.name].concat(field.type.jsonType === "array" ? [[]] : []);
255
+ return reduceType(field.type, reducer, acc, path.concat(segment), maxDepth - 1);
256
+ }, accumulator);
257
+ }
258
+ const BASE_WEIGHTS = [
259
+ { weight: 1, path: ["_id"] },
260
+ { weight: 1, path: ["_type"] }
261
+ ], PREVIEW_FIELD_WEIGHT_MAP = {
262
+ title: 10,
263
+ subtitle: 5,
264
+ description: 1.5
265
+ };
266
+ function deriveFromPreview(type, maxDepth) {
267
+ const select = type?.preview?.select;
268
+ if (!select)
269
+ return [];
270
+ const fields = [];
271
+ for (const fieldName of Object.keys(select)) {
272
+ if (!(fieldName in PREVIEW_FIELD_WEIGHT_MAP))
273
+ continue;
274
+ const path = select[fieldName].split(".");
275
+ maxDepth > -1 && path.length - 1 > maxDepth || fields.push({
276
+ weight: PREVIEW_FIELD_WEIGHT_MAP[fieldName],
277
+ path
278
+ });
279
+ }
280
+ return fields;
281
+ }
282
+ function getCachedStringFieldPaths(type, maxDepth) {
283
+ const symbol = getStringFieldSymbol(maxDepth);
284
+ return type[symbol] || (type[symbol] = uniqBy(
285
+ [
286
+ ...BASE_WEIGHTS,
287
+ ...deriveFromPreview(type, maxDepth),
288
+ ...getStringFieldPaths(type, maxDepth).map((path) => ({ weight: 1, path })),
289
+ ...getPortableTextFieldPaths(type, maxDepth).map((path) => ({
290
+ weight: 1,
291
+ path,
292
+ mapWith: "pt::text"
293
+ }))
294
+ ],
295
+ (spec) => spec.path.join(".")
296
+ )), type[symbol];
297
+ }
298
+ function getCachedBaseFieldPaths(type, maxDepth) {
299
+ const symbol = getStringFieldSymbol(maxDepth);
300
+ return type[symbol] || (type[symbol] = uniqBy(
301
+ [...BASE_WEIGHTS, ...deriveFromPreview(type, maxDepth)],
302
+ (spec) => spec.path.join(".")
303
+ )), type[symbol];
304
+ }
305
+ function getStringFieldPaths(type, maxDepth) {
306
+ return reduceType(type, (accumulator, childType, path) => childType.jsonType === "string" ? [...accumulator, path] : accumulator, [], [], maxDepth);
307
+ }
308
+ function getPortableTextFieldPaths(type, maxDepth) {
309
+ return reduceType(type, (accumulator, childType, path) => isPortableTextArray(childType) ? [...accumulator, path] : accumulator, [], [], maxDepth);
310
+ }
311
+ function resolveSearchConfigForBaseFieldPaths(type, maxDepth) {
312
+ return getCachedBaseFieldPaths(type, normalizeMaxDepth(maxDepth));
313
+ }
314
+ function resolveSearchConfig(type, maxDepth) {
315
+ return getCachedStringFieldPaths(type, normalizeMaxDepth(maxDepth));
316
+ }
317
+ function normalizeMaxDepth(maxDepth) {
318
+ return !isFinite(maxDepth) || maxDepth < 1 || maxDepth > DEFAULT_MAX_FIELD_DEPTH ? DEFAULT_MAX_FIELD_DEPTH - 1 : maxDepth - 1;
319
+ }
31
320
  function lazyGetter(target, key, getter, config = {}) {
32
321
  return Object.defineProperty(target, key, {
33
322
  configurable: !0,
@@ -533,102 +822,18 @@ const OVERRIDABLE_FIELDS$d = [...DEFAULT_OVERRIDEABLE_FIELDS], BOOLEAN_CORE = {
533
822
  function subtype(parent) {
534
823
  return {
535
824
  get() {
536
- return parent;
537
- },
538
- extend: (extensionDef) => {
539
- const subOwnProps = pick(extensionDef, OVERRIDABLE_FIELDS$d), current = Object.assign({}, parent, subOwnProps, {
540
- type: parent
541
- });
542
- return hiddenGetter(current, OWN_PROPS_NAME, subOwnProps), subtype(current);
543
- }
544
- };
545
- }
546
- }
547
- }, 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);
548
- function reduceType(type, reducer, acc, path = [], maxDepth) {
549
- if (maxDepth < 0)
550
- return acc;
551
- const accumulator = reducer(acc, type, path);
552
- 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;
553
- }
554
- function reduceArray(arrayType, reducer, accumulator, path, maxDepth) {
555
- return arrayType.of.reduce(
556
- (acc, ofType) => reduceType(ofType, reducer, acc, path, maxDepth - 1),
557
- accumulator
558
- );
559
- }
560
- function reduceObject(objectType, reducer, accumulator, path, maxDepth) {
561
- const isPtBlock = isPortableTextBlock(objectType);
562
- return objectType.fields.reduce((acc, field) => {
563
- if (isPtBlock && portableTextFields.includes(field.name))
564
- return acc;
565
- const segment = [field.name].concat(field.type.jsonType === "array" ? [[]] : []);
566
- return reduceType(field.type, reducer, acc, path.concat(segment), maxDepth - 1);
567
- }, accumulator);
568
- }
569
- const BASE_WEIGHTS = [
570
- { weight: 1, path: ["_id"] },
571
- { weight: 1, path: ["_type"] }
572
- ], PREVIEW_FIELD_WEIGHT_MAP = {
573
- title: 10,
574
- subtitle: 5,
575
- description: 1.5
576
- };
577
- function deriveFromPreview(type, maxDepth) {
578
- const select = type?.preview?.select;
579
- if (!select)
580
- return [];
581
- const fields = [];
582
- for (const fieldName of Object.keys(select)) {
583
- if (!(fieldName in PREVIEW_FIELD_WEIGHT_MAP))
584
- continue;
585
- const path = select[fieldName].split(".");
586
- maxDepth > -1 && path.length - 1 > maxDepth || fields.push({
587
- weight: PREVIEW_FIELD_WEIGHT_MAP[fieldName],
588
- path
589
- });
825
+ return parent;
826
+ },
827
+ extend: (extensionDef) => {
828
+ const subOwnProps = pick(extensionDef, OVERRIDABLE_FIELDS$d), current = Object.assign({}, parent, subOwnProps, {
829
+ type: parent
830
+ });
831
+ return hiddenGetter(current, OWN_PROPS_NAME, subOwnProps), subtype(current);
832
+ }
833
+ };
834
+ }
590
835
  }
591
- return fields;
592
- }
593
- function getCachedStringFieldPaths(type, maxDepth) {
594
- const symbol = getStringFieldSymbol(maxDepth);
595
- return type[symbol] || (type[symbol] = uniqBy(
596
- [
597
- ...BASE_WEIGHTS,
598
- ...deriveFromPreview(type, maxDepth),
599
- ...getStringFieldPaths(type, maxDepth).map((path) => ({ weight: 1, path })),
600
- ...getPortableTextFieldPaths(type, maxDepth).map((path) => ({
601
- weight: 1,
602
- path,
603
- mapWith: "pt::text"
604
- }))
605
- ],
606
- (spec) => spec.path.join(".")
607
- )), type[symbol];
608
- }
609
- function getCachedBaseFieldPaths(type, maxDepth) {
610
- const symbol = getStringFieldSymbol(maxDepth);
611
- return type[symbol] || (type[symbol] = uniqBy(
612
- [...BASE_WEIGHTS, ...deriveFromPreview(type, maxDepth)],
613
- (spec) => spec.path.join(".")
614
- )), type[symbol];
615
- }
616
- function getStringFieldPaths(type, maxDepth) {
617
- return reduceType(type, (accumulator, childType, path) => childType.jsonType === "string" ? [...accumulator, path] : accumulator, [], [], maxDepth);
618
- }
619
- function getPortableTextFieldPaths(type, maxDepth) {
620
- return reduceType(type, (accumulator, childType, path) => isPortableTextArray(childType) ? [...accumulator, path] : accumulator, [], [], maxDepth);
621
- }
622
- function resolveSearchConfigForBaseFieldPaths(type, maxDepth) {
623
- return getCachedBaseFieldPaths(type, normalizeMaxDepth(maxDepth));
624
- }
625
- function resolveSearchConfig(type, maxDepth) {
626
- return getCachedStringFieldPaths(type, normalizeMaxDepth(maxDepth));
627
- }
628
- function normalizeMaxDepth(maxDepth) {
629
- return !isFinite(maxDepth) || maxDepth < 1 || maxDepth > DEFAULT_MAX_FIELD_DEPTH ? DEFAULT_MAX_FIELD_DEPTH - 1 : maxDepth - 1;
630
- }
631
- const REF_FIELD$2 = {
836
+ }, REF_FIELD$2 = {
632
837
  name: "_ref",
633
838
  title: "Referenced document ID",
634
839
  type: "string"
@@ -1510,212 +1715,6 @@ class DeprecatedDefaultSchema extends Schema {
1510
1715
  console.warn(stack);
1511
1716
  }
1512
1717
  }
1513
- const FIELD_REF = /* @__PURE__ */ Symbol.for("@sanity/schema/field-ref"), ruleConstraintTypes = [
1514
- "Array",
1515
- "Boolean",
1516
- "Date",
1517
- "Number",
1518
- "Object",
1519
- "String"
1520
- ], Rule = class Rule2 {
1521
- static FIELD_REF = FIELD_REF;
1522
- static array = (def) => new Rule2(def).type("Array");
1523
- static object = (def) => new Rule2(def).type("Object");
1524
- static string = (def) => new Rule2(def).type("String");
1525
- static number = (def) => new Rule2(def).type("Number");
1526
- static boolean = (def) => new Rule2(def).type("Boolean");
1527
- static dateTime = (def) => new Rule2(def).type("Date");
1528
- static valueOfField = (path) => ({
1529
- type: FIELD_REF,
1530
- path
1531
- });
1532
- _type = void 0;
1533
- _level = void 0;
1534
- _required = void 0;
1535
- _typeDef = void 0;
1536
- _message = void 0;
1537
- _rules = [];
1538
- _fieldRules = void 0;
1539
- constructor(typeDef) {
1540
- this._typeDef = typeDef, this.reset();
1541
- }
1542
- _mergeRequired(next) {
1543
- if (this._required === "required" || next._required === "required") return "required";
1544
- if (this._required === "optional" || next._required === "optional") return "optional";
1545
- }
1546
- // Alias to static method, since we often have access to an _instance_ of a rule but not the actual Rule class
1547
- valueOfField = Rule2.valueOfField.bind(Rule2);
1548
- error(message) {
1549
- const rule = this.clone();
1550
- return rule._level = "error", rule._message = message || void 0, rule;
1551
- }
1552
- warning(message) {
1553
- const rule = this.clone();
1554
- return rule._level = "warning", rule._message = message || void 0, rule;
1555
- }
1556
- info(message) {
1557
- const rule = this.clone();
1558
- return rule._level = "info", rule._message = message || void 0, rule;
1559
- }
1560
- reset() {
1561
- 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;
1562
- }
1563
- isRequired() {
1564
- return this._required === "required";
1565
- }
1566
- clone() {
1567
- const rule = new Rule2();
1568
- 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;
1569
- }
1570
- cloneWithRules(rules) {
1571
- const rule = this.clone(), newRules = /* @__PURE__ */ new Set();
1572
- return rules.forEach((curr) => {
1573
- curr.flag === "type" && (rule._type = curr.constraint), newRules.add(curr.flag);
1574
- }), rule._rules = rule._rules.filter((curr) => {
1575
- const disallowDuplicate = ["type", "uri", "email"].includes(curr.flag), isDuplicate = newRules.has(curr.flag);
1576
- return !(disallowDuplicate && isDuplicate);
1577
- }).concat(rules), rule;
1578
- }
1579
- merge(rule) {
1580
- if (this._type && rule._type && this._type !== rule._type)
1581
- throw new Error("merge() failed: conflicting types");
1582
- const newRule = this.cloneWithRules(rule._rules);
1583
- 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;
1584
- }
1585
- // Validation flag setters
1586
- type(targetType) {
1587
- const type = `${targetType.slice(0, 1).toUpperCase()}${targetType.slice(1)}`;
1588
- if (!ruleConstraintTypes.includes(type))
1589
- throw new Error(`Unknown type "${targetType}"`);
1590
- const rule = this.cloneWithRules([{ flag: "type", constraint: type }]);
1591
- return rule._type = type, rule;
1592
- }
1593
- all(children) {
1594
- return this.cloneWithRules([{ flag: "all", constraint: children }]);
1595
- }
1596
- either(children) {
1597
- return this.cloneWithRules([{ flag: "either", constraint: children }]);
1598
- }
1599
- // Shared rules
1600
- optional() {
1601
- const rule = this.cloneWithRules([{ flag: "presence", constraint: "optional" }]);
1602
- return rule._required = "optional", rule;
1603
- }
1604
- skip() {
1605
- const rule = this.clone();
1606
- return rule._rules = [], rule._required = "optional", rule._message = void 0, rule._level = "error", rule._fieldRules = void 0, rule;
1607
- }
1608
- required() {
1609
- const rule = this.cloneWithRules([{ flag: "presence", constraint: "required" }]);
1610
- return rule._required = "required", rule;
1611
- }
1612
- custom(fn, options = {}) {
1613
- return options.bypassConcurrencyLimit && Object.assign(fn, { bypassConcurrencyLimit: !0 }), this.cloneWithRules([{ flag: "custom", constraint: fn }]);
1614
- }
1615
- min(len) {
1616
- return this.cloneWithRules([{ flag: "min", constraint: len }]);
1617
- }
1618
- max(len) {
1619
- return this.cloneWithRules([{ flag: "max", constraint: len }]);
1620
- }
1621
- length(len) {
1622
- return this.cloneWithRules([{ flag: "length", constraint: len }]);
1623
- }
1624
- valid(value) {
1625
- const values = Array.isArray(value) ? value : [value];
1626
- return this.cloneWithRules([{ flag: "valid", constraint: values }]);
1627
- }
1628
- // Numbers only
1629
- integer() {
1630
- return this.cloneWithRules([{ flag: "integer" }]);
1631
- }
1632
- precision(limit) {
1633
- return this.cloneWithRules([{ flag: "precision", constraint: limit }]);
1634
- }
1635
- positive() {
1636
- return this.cloneWithRules([{ flag: "min", constraint: 0 }]);
1637
- }
1638
- negative() {
1639
- return this.cloneWithRules([{ flag: "lessThan", constraint: 0 }]);
1640
- }
1641
- greaterThan(num) {
1642
- return this.cloneWithRules([{ flag: "greaterThan", constraint: num }]);
1643
- }
1644
- lessThan(num) {
1645
- return this.cloneWithRules([{ flag: "lessThan", constraint: num }]);
1646
- }
1647
- // String only
1648
- uppercase() {
1649
- return this.cloneWithRules([{ flag: "stringCasing", constraint: "uppercase" }]);
1650
- }
1651
- lowercase() {
1652
- return this.cloneWithRules([{ flag: "stringCasing", constraint: "lowercase" }]);
1653
- }
1654
- regex(pattern, a, b) {
1655
- const name = typeof a == "string" ? a : a?.name ?? b?.name, invert = typeof a == "string" ? !1 : a?.invert ?? b?.invert, constraint = {
1656
- pattern,
1657
- name,
1658
- invert: invert || !1
1659
- };
1660
- return this.cloneWithRules([{ flag: "regex", constraint }]);
1661
- }
1662
- email() {
1663
- return this.cloneWithRules([{ flag: "email" }]);
1664
- }
1665
- uri(opts) {
1666
- const optsScheme = opts?.scheme || ["http", "https"], schemes = Array.isArray(optsScheme) ? optsScheme : [optsScheme];
1667
- if (!schemes.length)
1668
- throw new Error("scheme must have at least 1 scheme specified");
1669
- const constraint = {
1670
- options: {
1671
- scheme: schemes.map((scheme) => {
1672
- if (!(scheme instanceof RegExp) && typeof scheme != "string")
1673
- throw new Error("scheme must be a RegExp or a String");
1674
- return typeof scheme == "string" ? new RegExp(`^${escapeRegex(scheme)}$`) : scheme;
1675
- }),
1676
- allowRelative: opts?.allowRelative || !1,
1677
- relativeOnly: opts?.relativeOnly || !1,
1678
- allowCredentials: opts?.allowCredentials || !1
1679
- }
1680
- };
1681
- return this.cloneWithRules([{ flag: "uri", constraint }]);
1682
- }
1683
- // Array only
1684
- unique() {
1685
- return this.cloneWithRules([{ flag: "unique" }]);
1686
- }
1687
- // Objects only
1688
- reference() {
1689
- return this.cloneWithRules([{ flag: "reference" }]);
1690
- }
1691
- fields(rules) {
1692
- if (this._type !== "Object")
1693
- throw new Error("fields() can only be called on an object type");
1694
- const rule = this.cloneWithRules([]);
1695
- return rule._fieldRules = rules, rule;
1696
- }
1697
- assetRequired() {
1698
- const base = getBaseType(this._typeDef);
1699
- let assetType;
1700
- return base && ["image", "file"].includes(base.name) ? assetType = base.name === "image" ? "image" : "file" : assetType = "asset", this.cloneWithRules([{ flag: "assetRequired", constraint: { assetType } }]);
1701
- }
1702
- media(fn) {
1703
- return this.cloneWithRules([{ flag: "media", constraint: fn }]);
1704
- }
1705
- /**
1706
- * The validate method is not implemented in the base Rule class.
1707
- * It should be implemented by extending this class or injecting validation logic.
1708
- */
1709
- async validate(value, options) {
1710
- throw new Error("validate() method must be implemented by extending Rule class");
1711
- }
1712
- };
1713
- function getBaseType(type) {
1714
- return type && type.type ? getBaseType(type.type) : type;
1715
- }
1716
- function escapeRegex(string) {
1717
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1718
- }
1719
1718
  export {
1720
1719
  ALL_FIELDS_GROUP_NAME,
1721
1720
  DEFAULT_ANNOTATIONS,
@@ -1728,4 +1727,4 @@ export {
1728
1727
  resolveSearchConfig,
1729
1728
  resolveSearchConfigForBaseFieldPaths
1730
1729
  };
1731
- //# sourceMappingURL=Rule.js.map
1730
+ //# sourceMappingURL=Schema.js.map