@sanity/schema 5.0.0-next.0-9b570ece82-202507150640 → 5.0.0-next.7
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 +1 -1
- package/lib/{index.mjs → _chunks-es/Rule.js} +368 -62
- package/lib/_chunks-es/Rule.js.map +1 -0
- package/lib/_internal.d.ts +266 -20
- package/lib/_internal.js +1489 -737
- package/lib/_internal.js.map +1 -1
- package/lib/index.d.ts +10 -0
- package/lib/index.js +7 -1411
- package/lib/index.js.map +1 -1
- package/package.json +18 -19
- package/lib/_chunks-cjs/resolve.js +0 -111
- package/lib/_chunks-cjs/resolve.js.map +0 -1
- package/lib/_chunks-es/resolve.mjs +0 -109
- package/lib/_chunks-es/resolve.mjs.map +0 -1
- package/lib/_internal.d.mts +0 -185
- package/lib/_internal.mjs +0 -2131
- package/lib/_internal.mjs.map +0 -1
- package/lib/index.d.mts +0 -47
- package/lib/index.mjs.map +0 -1
package/lib/_internal.js
CHANGED
|
@@ -1,44 +1,128 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { SetBuilder, processSetSynchronization } from "@sanity/descriptors";
|
|
2
|
+
import isEqual from "lodash/isEqual.js";
|
|
3
|
+
import isObject from "lodash/isObject.js";
|
|
4
|
+
import { OWN_PROPS_NAME, Rule, Schema } from "./_chunks-es/Rule.js";
|
|
5
|
+
import { ALL_FIELDS_GROUP_NAME, DEFAULT_MAX_FIELD_DEPTH, resolveSearchConfig, resolveSearchConfigForBaseFieldPaths } from "./_chunks-es/Rule.js";
|
|
6
|
+
import difference from "lodash/difference.js";
|
|
7
|
+
import cloneDeep from "lodash/cloneDeep.js";
|
|
8
|
+
import flatten from "lodash/flatten.js";
|
|
9
|
+
import get from "lodash/get.js";
|
|
10
|
+
import uniq from "lodash/uniq.js";
|
|
11
|
+
import humanizeList from "humanize-list";
|
|
12
|
+
import partition from "lodash/partition.js";
|
|
13
|
+
import isPlainObject from "lodash/isPlainObject.js";
|
|
14
|
+
import omit from "lodash/omit.js";
|
|
15
|
+
import leven from "leven";
|
|
16
|
+
import inspect from "object-inspect";
|
|
17
|
+
import { createReferenceTypeNode } from "groq-js";
|
|
18
|
+
const MAX_IDLE_WORK = 8.333333333333334;
|
|
19
|
+
class IdleScheduler {
|
|
20
|
+
#durations = [];
|
|
21
|
+
#lastAwake;
|
|
22
|
+
constructor(durations) {
|
|
23
|
+
this.#lastAwake = performance.now(), this.#durations = durations;
|
|
24
|
+
}
|
|
25
|
+
async map(arr, fn) {
|
|
26
|
+
const result = [];
|
|
27
|
+
for (const val of arr) {
|
|
28
|
+
const pause = this._tryPause();
|
|
29
|
+
pause && await pause, result.push(fn(val));
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
async forEach(arr, fn) {
|
|
34
|
+
for (const val of arr) {
|
|
35
|
+
const pause = this._tryPause();
|
|
36
|
+
pause && await pause, fn(val);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async forEachIter(iter, fn) {
|
|
40
|
+
for (const val of iter) {
|
|
41
|
+
const pause = this._tryPause();
|
|
42
|
+
pause && await pause, fn(val);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Should be invoked at the end to also measure the last pause. */
|
|
46
|
+
end() {
|
|
47
|
+
this.#durations.push(performance.now() - this.#lastAwake);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Yields control back to the UI.
|
|
51
|
+
*/
|
|
52
|
+
_tryPause() {
|
|
53
|
+
const elapsed = performance.now() - this.#lastAwake;
|
|
54
|
+
if (!(elapsed < MAX_IDLE_WORK))
|
|
55
|
+
return this.#durations.push(elapsed), new Promise((resolve) => {
|
|
56
|
+
const done = () => {
|
|
57
|
+
this.#lastAwake = performance.now(), resolve();
|
|
58
|
+
};
|
|
59
|
+
typeof requestIdleCallback == "function" ? requestIdleCallback(done, { timeout: 1 }) : typeof requestAnimationFrame == "function" ? requestAnimationFrame(done) : setTimeout(done, 0);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const SYNC_SCHEDULER = {
|
|
64
|
+
async map(arr, fn) {
|
|
65
|
+
return arr.map(fn);
|
|
66
|
+
},
|
|
67
|
+
async forEach(arr, fn) {
|
|
68
|
+
return arr.forEach(fn);
|
|
69
|
+
},
|
|
70
|
+
async forEachIter(iter, fn) {
|
|
71
|
+
for (const val of iter)
|
|
72
|
+
fn(val);
|
|
73
|
+
}
|
|
74
|
+
}, MAX_DEPTH_UKNOWN = 5;
|
|
9
75
|
class DescriptorConverter {
|
|
10
|
-
opts;
|
|
11
76
|
cache = /* @__PURE__ */ new WeakMap();
|
|
12
|
-
constructor(opts) {
|
|
13
|
-
this.opts = opts;
|
|
14
|
-
}
|
|
15
77
|
/**
|
|
16
78
|
* Returns a synchronization object for a schema.
|
|
17
79
|
*
|
|
18
80
|
* This is automatically cached in a weak map.
|
|
19
81
|
*/
|
|
20
|
-
get(schema) {
|
|
82
|
+
async get(schema, opts) {
|
|
21
83
|
let value = this.cache.get(schema);
|
|
22
84
|
if (value) return value;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
85
|
+
let idleScheduler;
|
|
86
|
+
const scheduler = opts?.scheduler || (opts?.pauseDurations ? idleScheduler = new IdleScheduler(opts.pauseDurations) : SYNC_SCHEDULER), options = {
|
|
87
|
+
fields: /* @__PURE__ */ new Map(),
|
|
88
|
+
duplicateFields: /* @__PURE__ */ new Map(),
|
|
89
|
+
arrayElements: /* @__PURE__ */ new Map(),
|
|
90
|
+
duplicateArrayElements: /* @__PURE__ */ new Map()
|
|
91
|
+
}, namedTypes = await scheduler.map(schema.getLocalTypeNames(), (name) => {
|
|
92
|
+
const typeDef = convertTypeDef(schema.get(name), name, options);
|
|
93
|
+
return { name, typeDef };
|
|
94
|
+
}), rewriteMap = /* @__PURE__ */ new Map();
|
|
95
|
+
for (const [fieldDef, key] of options.duplicateFields.entries())
|
|
96
|
+
rewriteMap.set(fieldDef, { __type: "hoisted", key });
|
|
97
|
+
for (const [arrayElem, key] of options.duplicateArrayElements.entries())
|
|
98
|
+
rewriteMap.set(arrayElem, { __type: "hoisted", key });
|
|
99
|
+
const builder = new SetBuilder({ rewriteMap });
|
|
100
|
+
return await scheduler.forEachIter(options.duplicateFields.entries(), ([fieldDef, key]) => {
|
|
101
|
+
builder.addObject("sanity.schema.hoisted", { key, value: { ...fieldDef } });
|
|
102
|
+
}), await scheduler.forEachIter(options.duplicateArrayElements.entries(), ([arrayElem, key]) => {
|
|
103
|
+
builder.addObject("sanity.schema.hoisted", { key, value: { ...arrayElem } });
|
|
104
|
+
}), await scheduler.forEach(namedTypes, (namedType) => {
|
|
105
|
+
builder.addObject("sanity.schema.namedType", namedType);
|
|
106
|
+
}), schema.parent && builder.addSet(await this.get(schema.parent, { scheduler })), value = builder.build("sanity.schema.registry"), this.cache.set(schema, value), idleScheduler && idleScheduler.end(), value;
|
|
29
107
|
}
|
|
30
108
|
}
|
|
31
|
-
function convertCommonTypeDef(schemaType, opts) {
|
|
32
|
-
const ownProps =
|
|
109
|
+
function convertCommonTypeDef(schemaType, path, opts) {
|
|
110
|
+
const ownProps = OWN_PROPS_NAME in schemaType ? schemaType[OWN_PROPS_NAME] : schemaType;
|
|
33
111
|
let fields;
|
|
34
|
-
Array.isArray(ownProps.fields) && (fields = ownProps.fields.map(
|
|
35
|
-
|
|
112
|
+
Array.isArray(ownProps.fields) && (fields = ownProps.fields.map((field) => {
|
|
113
|
+
const fieldPath = `${path}.${field.name}`, value = opts.fields.get(field);
|
|
114
|
+
if (value) {
|
|
115
|
+
const otherPath = opts.duplicateFields.get(value);
|
|
116
|
+
return (!otherPath || isLessCanonicalName(fieldPath, otherPath)) && opts.duplicateFields.set(value, fieldPath), value;
|
|
117
|
+
}
|
|
118
|
+
const { name, group, fieldset, type } = field, converted = {
|
|
36
119
|
name,
|
|
37
|
-
typeDef: convertTypeDef(type),
|
|
120
|
+
typeDef: convertTypeDef(type, fieldPath, opts),
|
|
38
121
|
groups: arrayifyString(group),
|
|
39
122
|
fieldset
|
|
40
|
-
}
|
|
41
|
-
|
|
123
|
+
};
|
|
124
|
+
return opts.fields.set(field, converted), converted;
|
|
125
|
+
}));
|
|
42
126
|
let fieldsets;
|
|
43
127
|
Array.isArray(ownProps.fieldsets) && (fieldsets = filterStringKey(
|
|
44
128
|
"name",
|
|
@@ -58,16 +142,18 @@ function convertCommonTypeDef(schemaType, opts) {
|
|
|
58
142
|
Array.isArray(ownProps.groups) && (groups = filterStringKey(
|
|
59
143
|
"name",
|
|
60
144
|
ownProps.groups.map(
|
|
61
|
-
({ name, title, hidden, default: def }) => ({
|
|
145
|
+
({ name, title, hidden, default: def, i18n }) => ({
|
|
62
146
|
name,
|
|
63
147
|
title: maybeString(title),
|
|
64
148
|
hidden: conditionalTrue(hidden),
|
|
65
|
-
default: maybeTrue(def)
|
|
149
|
+
default: maybeTrue(def),
|
|
150
|
+
i18n: maybeI18n(i18n)
|
|
66
151
|
})
|
|
67
152
|
)
|
|
68
153
|
));
|
|
69
154
|
const reason = ownProps.deprecated?.reason;
|
|
70
|
-
|
|
155
|
+
let orderings;
|
|
156
|
+
return Array.isArray(ownProps.orderings) && (orderings = ownProps.orderings.map(maybeOrdering).filter((o) => o !== void 0)), {
|
|
71
157
|
title: maybeString(ownProps.title),
|
|
72
158
|
description: maybeStringOrJSX(ownProps.description),
|
|
73
159
|
readOnly: conditionalTrue(ownProps.readOnly),
|
|
@@ -80,11 +166,13 @@ function convertCommonTypeDef(schemaType, opts) {
|
|
|
80
166
|
rows: maybeNumberAsString(ownProps.rows),
|
|
81
167
|
fields,
|
|
82
168
|
fieldsets,
|
|
83
|
-
groups
|
|
169
|
+
groups,
|
|
170
|
+
validation: maybeValidations(ownProps),
|
|
171
|
+
orderings
|
|
84
172
|
};
|
|
85
173
|
}
|
|
86
|
-
function convertTypeDef(schemaType, opts) {
|
|
87
|
-
const common2 = convertCommonTypeDef(schemaType);
|
|
174
|
+
function convertTypeDef(schemaType, path, opts) {
|
|
175
|
+
const common2 = convertCommonTypeDef(schemaType, path, opts);
|
|
88
176
|
if (!schemaType.type)
|
|
89
177
|
return {
|
|
90
178
|
extends: null,
|
|
@@ -95,10 +183,18 @@ function convertTypeDef(schemaType, opts) {
|
|
|
95
183
|
case "array":
|
|
96
184
|
return {
|
|
97
185
|
extends: "array",
|
|
98
|
-
of: schemaType.of.map((ofType) =>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
186
|
+
of: schemaType.of.map((ofType, idx) => {
|
|
187
|
+
const itemPath = `${path}.${ofType.name}`, value = opts.arrayElements.get(ofType);
|
|
188
|
+
if (value) {
|
|
189
|
+
const otherPath = opts.duplicateArrayElements.get(value);
|
|
190
|
+
return (!otherPath || isLessCanonicalName(itemPath, otherPath)) && opts.duplicateArrayElements.set(value, itemPath), value;
|
|
191
|
+
}
|
|
192
|
+
const converted = {
|
|
193
|
+
name: ofType.name,
|
|
194
|
+
typeDef: convertTypeDef(ofType, `${path}.${ofType.name}`, opts)
|
|
195
|
+
};
|
|
196
|
+
return opts.arrayElements.set(ofType, converted), converted;
|
|
197
|
+
}),
|
|
102
198
|
...common2
|
|
103
199
|
};
|
|
104
200
|
case "reference":
|
|
@@ -147,7 +243,7 @@ function convertUnknown(val, seen = /* @__PURE__ */ new Set(), maxDepth = MAX_DE
|
|
|
147
243
|
if (typeof val == "function") return FUNCTION_MARKER;
|
|
148
244
|
if (seen.has(val))
|
|
149
245
|
return CYCLIC_MARKER;
|
|
150
|
-
if (seen.add(val),
|
|
246
|
+
if (seen.add(val), isObject(val)) {
|
|
151
247
|
if (Array.isArray(val))
|
|
152
248
|
return val.map((elem) => {
|
|
153
249
|
const res = convertUnknown(elem, seen, maxDepth - 1);
|
|
@@ -171,13 +267,239 @@ function convertUnknown(val, seen = /* @__PURE__ */ new Set(), maxDepth = MAX_DE
|
|
|
171
267
|
}
|
|
172
268
|
function maybeStringOrJSX(val) {
|
|
173
269
|
if (typeof val == "string") return val;
|
|
174
|
-
if (val &&
|
|
270
|
+
if (isObject(val) && "$$typeof" in val && "type" in val && "props" in val) {
|
|
175
271
|
const { type, props } = val, strType = typeof type == "function" ? type.name : type;
|
|
176
272
|
return typeof strType != "string" ? void 0 : { __type: "jsx", type: strType, props: convertUnknown(props) };
|
|
177
273
|
}
|
|
178
274
|
}
|
|
275
|
+
function maybeValidations(obj) {
|
|
276
|
+
if (!isObject(obj) || !("type" in obj)) return;
|
|
277
|
+
const impliedRules = [];
|
|
278
|
+
switch ("options" in obj && isObject(obj.options) && "list" in obj.options && Array.isArray(obj.options.list) && impliedRules.push({
|
|
279
|
+
type: "enum",
|
|
280
|
+
values: obj.options.list.map((o) => convertUnknown(extractValueFromListOption(o, obj))).filter((v) => v !== void 0)
|
|
281
|
+
}), obj.type) {
|
|
282
|
+
case "url":
|
|
283
|
+
impliedRules.push({
|
|
284
|
+
type: "uri",
|
|
285
|
+
allowRelative: !1
|
|
286
|
+
});
|
|
287
|
+
break;
|
|
288
|
+
case "slug":
|
|
289
|
+
impliedRules.push({
|
|
290
|
+
type: "custom"
|
|
291
|
+
});
|
|
292
|
+
break;
|
|
293
|
+
case "reference":
|
|
294
|
+
impliedRules.push({
|
|
295
|
+
type: "reference"
|
|
296
|
+
});
|
|
297
|
+
break;
|
|
298
|
+
case "email":
|
|
299
|
+
impliedRules.push({
|
|
300
|
+
type: "email"
|
|
301
|
+
});
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
if (!("validation" in obj) || !obj.validation)
|
|
305
|
+
return impliedRules.length > 0 ? [
|
|
306
|
+
{
|
|
307
|
+
level: "error",
|
|
308
|
+
rules: impliedRules
|
|
309
|
+
}
|
|
310
|
+
] : void 0;
|
|
311
|
+
const validations = [], rules = Array.isArray(obj.validation) ? obj.validation : [obj.validation];
|
|
312
|
+
for (const rule of rules) {
|
|
313
|
+
const validation = maybeValidation(rule);
|
|
314
|
+
if (validation === void 0)
|
|
315
|
+
continue;
|
|
316
|
+
const rulesToAdd = impliedRules.filter((ir) => !validation.rules.some((r) => isEqual(r, ir)));
|
|
317
|
+
rulesToAdd.length > 0 && validation.rules.unshift(...rulesToAdd), !validations.some((v) => isEqual(v, validation)) && validations.push(validation);
|
|
318
|
+
}
|
|
319
|
+
return validations.length > 0 ? validations : void 0;
|
|
320
|
+
}
|
|
321
|
+
function hasValueField(typeDef) {
|
|
322
|
+
return !typeDef || typeof typeDef != "object" ? !1 : "fields" in typeDef ? Array.isArray(typeDef.fields) ? typeDef.fields.some((field) => field.name === "value") : !1 : "type" in typeDef && typeDef.type ? hasValueField(typeDef.type) : !1;
|
|
323
|
+
}
|
|
324
|
+
function extractValueFromListOption(option, typeDef) {
|
|
325
|
+
return typeDef.jsonType === "object" && hasValueField(typeDef) ? option : isObject(option) && "value" in option && option.value ? option.value : option;
|
|
326
|
+
}
|
|
327
|
+
function maybeValidation(val) {
|
|
328
|
+
if (val) {
|
|
329
|
+
if (isIRuleFunction(val))
|
|
330
|
+
try {
|
|
331
|
+
const result = val(new Rule());
|
|
332
|
+
if (isIRule(result))
|
|
333
|
+
return maybeValidation(result);
|
|
334
|
+
throw new Error("failed to convert to plain rule");
|
|
335
|
+
} catch {
|
|
336
|
+
return {
|
|
337
|
+
level: "error",
|
|
338
|
+
rules: [{ type: "custom", name: "function" }]
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
if (isIRule(val)) {
|
|
342
|
+
const level = val._level || "error", message = maybeValidationMessage(val._message), rules = [];
|
|
343
|
+
for (const spec of val._rules || []) {
|
|
344
|
+
const optional = val._required === "optional" || void 0, convertedRule = convertRuleSpec(spec, optional);
|
|
345
|
+
convertedRule !== void 0 && (rules.some((r) => isEqual(r, convertedRule)) || rules.push(convertedRule));
|
|
346
|
+
}
|
|
347
|
+
return rules.length === 0 ? void 0 : {
|
|
348
|
+
level,
|
|
349
|
+
rules,
|
|
350
|
+
...message && { message }
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function isIRule(val) {
|
|
356
|
+
return isObject(val) && "_rules" in val;
|
|
357
|
+
}
|
|
358
|
+
function maybeValidationMessage(val) {
|
|
359
|
+
if (typeof val == "string") return val;
|
|
360
|
+
if (!isObject(val) || Array.isArray(val)) return;
|
|
361
|
+
const objectMessage = {};
|
|
362
|
+
for (const [field, value] of Object.entries(val))
|
|
363
|
+
typeof field != "string" || typeof value != "string" || (objectMessage[field] = value);
|
|
364
|
+
return Object.keys(objectMessage).length > 0 ? objectMessage : void 0;
|
|
365
|
+
}
|
|
366
|
+
function isIRuleFunction(val) {
|
|
367
|
+
return typeof val == "function";
|
|
368
|
+
}
|
|
369
|
+
function convertRuleSpec(spec, optional) {
|
|
370
|
+
if (!isObject(spec) || !("flag" in spec))
|
|
371
|
+
return;
|
|
372
|
+
const constraint = "constraint" in spec ? spec.constraint : void 0;
|
|
373
|
+
switch (spec.flag) {
|
|
374
|
+
case "integer":
|
|
375
|
+
return { type: "integer" };
|
|
376
|
+
case "email":
|
|
377
|
+
return { type: "email" };
|
|
378
|
+
case "unique":
|
|
379
|
+
return { type: "uniqueItems" };
|
|
380
|
+
case "reference":
|
|
381
|
+
return { type: "reference" };
|
|
382
|
+
case "assetRequired":
|
|
383
|
+
return { type: "assetRequired" };
|
|
384
|
+
case "stringCasing":
|
|
385
|
+
return constraint === "uppercase" ? { type: "uppercase" } : constraint === "lowercase" ? { type: "lowercase" } : void 0;
|
|
386
|
+
case "all":
|
|
387
|
+
if (Array.isArray(constraint)) {
|
|
388
|
+
const children = constraint.map((childRule) => maybeValidation(childRule)).filter((c) => c !== void 0);
|
|
389
|
+
if (children.length > 0)
|
|
390
|
+
return { type: "allOf", children };
|
|
391
|
+
}
|
|
392
|
+
return;
|
|
393
|
+
case "either":
|
|
394
|
+
if (Array.isArray(constraint)) {
|
|
395
|
+
const children = constraint.map((childRule) => maybeValidation(childRule)).filter((c) => c !== void 0);
|
|
396
|
+
if (children.length > 0)
|
|
397
|
+
return { type: "anyOf", children };
|
|
398
|
+
}
|
|
399
|
+
return;
|
|
400
|
+
case "valid":
|
|
401
|
+
return Array.isArray(constraint) ? {
|
|
402
|
+
type: "enum",
|
|
403
|
+
values: constraint.map((c) => convertUnknown(c)).filter((v) => v !== void 0)
|
|
404
|
+
} : void 0;
|
|
405
|
+
case "min":
|
|
406
|
+
return { type: "minimum", value: convertConstraintValue(constraint) };
|
|
407
|
+
case "max":
|
|
408
|
+
return { type: "maximum", value: convertConstraintValue(constraint) };
|
|
409
|
+
case "length":
|
|
410
|
+
return { type: "length", value: convertConstraintValue(constraint) };
|
|
411
|
+
case "precision":
|
|
412
|
+
return { type: "precision", value: convertConstraintValue(constraint) };
|
|
413
|
+
case "lessThan":
|
|
414
|
+
return { type: "exclusiveMaximum", value: convertConstraintValue(constraint) };
|
|
415
|
+
case "greaterThan":
|
|
416
|
+
return { type: "exclusiveMinimum", value: convertConstraintValue(constraint) };
|
|
417
|
+
case "regex":
|
|
418
|
+
if (isObject(constraint) && "pattern" in constraint) {
|
|
419
|
+
const { pattern } = constraint, invert = "invert" in constraint ? maybeBoolean(constraint.invert) : void 0;
|
|
420
|
+
if (pattern instanceof RegExp)
|
|
421
|
+
return {
|
|
422
|
+
type: "regex",
|
|
423
|
+
pattern: pattern.source,
|
|
424
|
+
...invert && { invert: !0 }
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
return;
|
|
428
|
+
case "uri": {
|
|
429
|
+
const allowRelative = isObject(constraint) && "options" in constraint && isObject(constraint.options) && "allowRelative" in constraint.options ? maybeBoolean(constraint.options.allowRelative) : void 0;
|
|
430
|
+
return {
|
|
431
|
+
type: "uri",
|
|
432
|
+
...allowRelative !== void 0 && { allowRelative }
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
case "custom":
|
|
436
|
+
return { type: "custom", ...optional && { optional } };
|
|
437
|
+
case "media":
|
|
438
|
+
return { type: "custom", name: "media" };
|
|
439
|
+
case "type":
|
|
440
|
+
return;
|
|
441
|
+
case "presence":
|
|
442
|
+
return constraint === "required" ? { type: "required" } : void 0;
|
|
443
|
+
default:
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
function convertConstraintValue(constraint) {
|
|
448
|
+
return isObject(constraint) && "type" in constraint && "path" in constraint && constraint.type && constraint.path ? {
|
|
449
|
+
type: "fieldReference",
|
|
450
|
+
path: Array.isArray(constraint.path) ? constraint.path : [constraint.path]
|
|
451
|
+
} : String(constraint);
|
|
452
|
+
}
|
|
453
|
+
function maybeBoolean(val) {
|
|
454
|
+
if (typeof val == "boolean")
|
|
455
|
+
return val;
|
|
456
|
+
}
|
|
457
|
+
function maybeI18n(val) {
|
|
458
|
+
if (!isObject(val) || Array.isArray(val)) return;
|
|
459
|
+
const localizedMessage = {};
|
|
460
|
+
for (const entry of Object.entries(val))
|
|
461
|
+
if (isI18nEntry(entry)) {
|
|
462
|
+
const [field, value] = entry;
|
|
463
|
+
localizedMessage[field] = {
|
|
464
|
+
ns: value.ns,
|
|
465
|
+
key: value.key
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
return Object.keys(localizedMessage).length > 0 ? localizedMessage : void 0;
|
|
469
|
+
}
|
|
470
|
+
function isI18nEntry(entry) {
|
|
471
|
+
const [key, value] = entry;
|
|
472
|
+
return typeof key == "string" && !!value && typeof value == "object" && "key" in value && "ns" in value && typeof value.key == "string" && typeof value.ns == "string";
|
|
473
|
+
}
|
|
474
|
+
function maybeOrdering(val) {
|
|
475
|
+
if (!isObject(val) || Array.isArray(val)) return;
|
|
476
|
+
const name = "name" in val && typeof val.name == "string" ? val.name : void 0;
|
|
477
|
+
if (name === void 0) return;
|
|
478
|
+
const title = "title" in val && typeof val.title == "string" ? val.title : name, by = "by" in val && Array.isArray(val.by) ? val.by : [], orderingBy = [];
|
|
479
|
+
for (const item of by) {
|
|
480
|
+
const orderingItem = maybeOrderingBy(item);
|
|
481
|
+
orderingItem && orderingBy.push(orderingItem);
|
|
482
|
+
}
|
|
483
|
+
if (orderingBy.length === 0) return;
|
|
484
|
+
const i18n = "i18n" in val ? maybeI18n(val.i18n) : void 0;
|
|
485
|
+
return {
|
|
486
|
+
name,
|
|
487
|
+
title,
|
|
488
|
+
by: orderingBy,
|
|
489
|
+
...i18n && { i18n }
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
function maybeOrderingBy(val) {
|
|
493
|
+
if (!isObject(val) || Array.isArray(val)) return;
|
|
494
|
+
const field = "field" in val && typeof val.field == "string" ? val.field : void 0, direction = "direction" in val && (val.direction === "asc" || val.direction === "desc") ? val.direction : void 0;
|
|
495
|
+
if (!(!field || !direction))
|
|
496
|
+
return { field, direction };
|
|
497
|
+
}
|
|
498
|
+
function isLessCanonicalName(a, b) {
|
|
499
|
+
return a.length < b.length || a.length === b.length && a < b;
|
|
500
|
+
}
|
|
179
501
|
function processSchemaSynchronization(sync, response) {
|
|
180
|
-
return
|
|
502
|
+
return processSetSynchronization(sync, response);
|
|
181
503
|
}
|
|
182
504
|
const ACTIONS_FLAG = "__experimental_actions", DEFAULT_ACTIONS = ["create", "update", "delete", "publish"], VALID_ACTIONS = DEFAULT_ACTIONS, readActions = (schemaType) => ACTIONS_FLAG in schemaType ? schemaType[ACTIONS_FLAG] : DEFAULT_ACTIONS, validateActions = (typeName, actions) => {
|
|
183
505
|
if (!Array.isArray(actions))
|
|
@@ -186,7 +508,7 @@ const ACTIONS_FLAG = "__experimental_actions", DEFAULT_ACTIONS = ["create", "upd
|
|
|
186
508
|
", "
|
|
187
509
|
)}`
|
|
188
510
|
);
|
|
189
|
-
const invalid =
|
|
511
|
+
const invalid = difference(actions, VALID_ACTIONS);
|
|
190
512
|
if (invalid.length > 0)
|
|
191
513
|
throw new Error(
|
|
192
514
|
`Invalid action${invalid.length > 1 ? "s" : ""} configured for schema type "${typeName}": ${invalid.join(
|
|
@@ -475,12 +797,16 @@ var assetSourceData = {
|
|
|
475
797
|
id: "_id",
|
|
476
798
|
title: "originalFilename",
|
|
477
799
|
mimeType: "mimeType",
|
|
478
|
-
size: "size"
|
|
800
|
+
size: "size",
|
|
801
|
+
media: "media"
|
|
479
802
|
},
|
|
480
803
|
prepare(doc) {
|
|
481
804
|
return {
|
|
482
805
|
title: doc.title || typeof doc.path == "string" && doc.path.split("/").slice(-1)[0],
|
|
483
|
-
media: {
|
|
806
|
+
media: {
|
|
807
|
+
asset: { _ref: doc.id },
|
|
808
|
+
...doc.media ? { media: doc.media } : {}
|
|
809
|
+
},
|
|
484
810
|
subtitle: `${doc.mimeType} (${(Number(doc.size) / 1024 / 1024).toFixed(2)} MB)`
|
|
485
811
|
};
|
|
486
812
|
}
|
|
@@ -499,19 +825,23 @@ var assetSourceData = {
|
|
|
499
825
|
fields: [
|
|
500
826
|
{
|
|
501
827
|
name: "top",
|
|
502
|
-
type: "number"
|
|
828
|
+
type: "number",
|
|
829
|
+
validation: (Rule2) => Rule2.required()
|
|
503
830
|
},
|
|
504
831
|
{
|
|
505
832
|
name: "bottom",
|
|
506
|
-
type: "number"
|
|
833
|
+
type: "number",
|
|
834
|
+
validation: (Rule2) => Rule2.required()
|
|
507
835
|
},
|
|
508
836
|
{
|
|
509
837
|
name: "left",
|
|
510
|
-
type: "number"
|
|
838
|
+
type: "number",
|
|
839
|
+
validation: (Rule2) => Rule2.required()
|
|
511
840
|
},
|
|
512
841
|
{
|
|
513
842
|
name: "right",
|
|
514
|
-
type: "number"
|
|
843
|
+
type: "number",
|
|
844
|
+
validation: (Rule2) => Rule2.required()
|
|
515
845
|
}
|
|
516
846
|
]
|
|
517
847
|
}, imageDimensions = {
|
|
@@ -519,9 +849,27 @@ var assetSourceData = {
|
|
|
519
849
|
type: "object",
|
|
520
850
|
title: "Image dimensions",
|
|
521
851
|
fields: [
|
|
522
|
-
{
|
|
523
|
-
|
|
524
|
-
|
|
852
|
+
{
|
|
853
|
+
name: "height",
|
|
854
|
+
type: "number",
|
|
855
|
+
title: "Height",
|
|
856
|
+
readOnly: !0,
|
|
857
|
+
validation: (Rule2) => Rule2.required()
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
name: "width",
|
|
861
|
+
type: "number",
|
|
862
|
+
title: "Width",
|
|
863
|
+
readOnly: !0,
|
|
864
|
+
validation: (Rule2) => Rule2.required()
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
name: "aspectRatio",
|
|
868
|
+
type: "number",
|
|
869
|
+
title: "Aspect ratio",
|
|
870
|
+
readOnly: !0,
|
|
871
|
+
validation: (Rule2) => Rule2.required()
|
|
872
|
+
}
|
|
525
873
|
]
|
|
526
874
|
}, imageHotspot = {
|
|
527
875
|
name: "sanity.imageHotspot",
|
|
@@ -530,19 +878,23 @@ var assetSourceData = {
|
|
|
530
878
|
fields: [
|
|
531
879
|
{
|
|
532
880
|
name: "x",
|
|
533
|
-
type: "number"
|
|
881
|
+
type: "number",
|
|
882
|
+
validation: (Rule2) => Rule2.required()
|
|
534
883
|
},
|
|
535
884
|
{
|
|
536
885
|
name: "y",
|
|
537
|
-
type: "number"
|
|
886
|
+
type: "number",
|
|
887
|
+
validation: (Rule2) => Rule2.required()
|
|
538
888
|
},
|
|
539
889
|
{
|
|
540
890
|
name: "height",
|
|
541
|
-
type: "number"
|
|
891
|
+
type: "number",
|
|
892
|
+
validation: (Rule2) => Rule2.required()
|
|
542
893
|
},
|
|
543
894
|
{
|
|
544
895
|
name: "width",
|
|
545
|
-
type: "number"
|
|
896
|
+
type: "number",
|
|
897
|
+
validation: (Rule2) => Rule2.required()
|
|
546
898
|
}
|
|
547
899
|
]
|
|
548
900
|
}, imageMetadata = {
|
|
@@ -632,7 +984,7 @@ var assetSourceData = {
|
|
|
632
984
|
name: "current",
|
|
633
985
|
title: "Current slug",
|
|
634
986
|
type: "string",
|
|
635
|
-
validation: (
|
|
987
|
+
validation: (Rule2) => Rule2.required()
|
|
636
988
|
},
|
|
637
989
|
{
|
|
638
990
|
// The source field is deprecated/unused, but leaving it included and hidden
|
|
@@ -657,537 +1009,221 @@ const builtinTypes = [
|
|
|
657
1009
|
imageDimensions,
|
|
658
1010
|
imagePalette,
|
|
659
1011
|
imagePaletteSwatch
|
|
660
|
-
],
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
1012
|
+
], HELP_IDS = {
|
|
1013
|
+
TYPE_INVALID: "schema-type-invalid",
|
|
1014
|
+
TYPE_IS_ESM_MODULE: "schema-type-is-esm-module",
|
|
1015
|
+
TYPE_NAME_RESERVED: "schema-type-name-reserved",
|
|
1016
|
+
TYPE_MISSING_NAME: "schema-type-missing-name-or-type",
|
|
1017
|
+
TYPE_MISSING_TYPE: "schema-type-missing-name-or-type",
|
|
1018
|
+
TYPE_TITLE_RECOMMENDED: "schema-type-title-is-recommended",
|
|
1019
|
+
TYPE_TITLE_INVALID: "schema-type-title-is-recommended",
|
|
1020
|
+
OBJECT_FIELDS_INVALID: "schema-object-fields-invalid",
|
|
1021
|
+
OBJECT_FIELD_NOT_UNIQUE: "schema-object-fields-invalid",
|
|
1022
|
+
OBJECT_FIELD_NAME_INVALID: "schema-object-fields-invalid",
|
|
1023
|
+
OBJECT_FIELD_DEFINITION_INVALID_TYPE: "schema-object-fields-invalid",
|
|
1024
|
+
ARRAY_PREDEFINED_CHOICES_INVALID: "schema-predefined-choices-invalid",
|
|
1025
|
+
ARRAY_OF_ARRAY: "schema-array-of-array",
|
|
1026
|
+
ARRAY_OF_INVALID: "schema-array-of-invalid",
|
|
1027
|
+
ARRAY_OF_NOT_UNIQUE: "schema-array-of-invalid",
|
|
1028
|
+
ARRAY_OF_TYPE_GLOBAL_TYPE_CONFLICT: "schema-array-of-type-global-type-conflict",
|
|
1029
|
+
ARRAY_OF_TYPE_BUILTIN_TYPE_CONFLICT: "schema-array-of-type-builtin-type-conflict",
|
|
1030
|
+
REFERENCE_TO_INVALID: "schema-reference-to-invalid",
|
|
1031
|
+
REFERENCE_TO_NOT_UNIQUE: "schema-reference-to-invalid",
|
|
1032
|
+
REFERENCE_INVALID_OPTIONS: "schema-reference-invalid-options",
|
|
1033
|
+
REFERENCE_INVALID_OPTIONS_LOCATION: "schema-reference-options-nesting",
|
|
1034
|
+
REFERENCE_INVALID_FILTER_PARAMS_COMBINATION: "schema-reference-filter-params-combination",
|
|
1035
|
+
SLUG_SLUGIFY_FN_RENAMED: "slug-slugifyfn-renamed",
|
|
1036
|
+
ASSET_METADATA_FIELD_INVALID: "asset-metadata-field-invalid",
|
|
1037
|
+
CROSS_DATASET_REFERENCE_INVALID: "cross-dataset-reference-invalid",
|
|
1038
|
+
GLOBAL_DOCUMENT_REFERENCE_INVALID: "global-document-reference-invalid",
|
|
1039
|
+
DEPRECATED_BLOCKEDITOR_KEY: "schema-deprecated-blockeditor-key",
|
|
1040
|
+
STANDALONE_BLOCK_TYPE: "schema-standalone-block-type"
|
|
1041
|
+
};
|
|
1042
|
+
function createValidationResult(severity, message, helpId) {
|
|
1043
|
+
if (helpId && !Object.keys(HELP_IDS).some((id) => HELP_IDS[id] === helpId))
|
|
1044
|
+
throw new Error(
|
|
1045
|
+
`Used the unknown helpId "${helpId}", please add it to the array in createValidationResult.js`
|
|
1046
|
+
);
|
|
1047
|
+
return {
|
|
1048
|
+
severity,
|
|
1049
|
+
message,
|
|
1050
|
+
helpId
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
const error = (message, helpId) => createValidationResult("error", message, helpId), warning = (message, helpId) => createValidationResult("warning", message, helpId);
|
|
1054
|
+
function groupProblems(types) {
|
|
1055
|
+
return flatten(types.map((type) => getTypeProblems(type))).filter(
|
|
1056
|
+
(type) => type.problems.length > 0
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
function createTypeWithMembersProblemsAccessor(memberPropertyName, getMembers = (type) => get(type, memberPropertyName)) {
|
|
1060
|
+
return function(type, parentPath) {
|
|
1061
|
+
const currentPath = [
|
|
1062
|
+
...parentPath,
|
|
1063
|
+
{ kind: "type", type: type.type, name: type.name }
|
|
1064
|
+
], members = getMembers(type) || [], memberProblems = Array.isArray(members) ? members.map((memberType) => {
|
|
1065
|
+
const propertySegment = {
|
|
1066
|
+
kind: "property",
|
|
1067
|
+
name: memberPropertyName
|
|
1068
|
+
}, memberPath = [...currentPath, propertySegment];
|
|
1069
|
+
return getTypeProblems(memberType, memberPath);
|
|
1070
|
+
}) : [
|
|
1071
|
+
[
|
|
1072
|
+
{
|
|
1073
|
+
path: currentPath,
|
|
1074
|
+
problems: [error(`Member declaration (${memberPropertyName}) is not an array`)]
|
|
708
1075
|
}
|
|
709
|
-
|
|
1076
|
+
]
|
|
1077
|
+
];
|
|
1078
|
+
return [
|
|
1079
|
+
{
|
|
1080
|
+
path: currentPath,
|
|
1081
|
+
problems: type._problems || []
|
|
1082
|
+
},
|
|
1083
|
+
...flatten(memberProblems)
|
|
1084
|
+
];
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
const arrify = (val) => Array.isArray(val) ? val : typeof val > "u" && [] || [val], getObjectProblems = createTypeWithMembersProblemsAccessor("fields"), getImageProblems = createTypeWithMembersProblemsAccessor("fields"), getFileProblems = createTypeWithMembersProblemsAccessor("fields"), getArrayProblems = createTypeWithMembersProblemsAccessor("of"), getReferenceProblems = createTypeWithMembersProblemsAccessor(
|
|
1088
|
+
"to",
|
|
1089
|
+
(type) => "to" in type ? arrify(type.to) : []
|
|
1090
|
+
), getBlockAnnotationProblems = createTypeWithMembersProblemsAccessor("marks.annotations"), getBlockMemberProblems = createTypeWithMembersProblemsAccessor("of"), getBlockProblems = (type, problems) => [
|
|
1091
|
+
...getBlockAnnotationProblems(type, problems),
|
|
1092
|
+
...getBlockMemberProblems(type, problems)
|
|
1093
|
+
];
|
|
1094
|
+
function getDefaultProblems(type, path = []) {
|
|
1095
|
+
return [
|
|
1096
|
+
{
|
|
1097
|
+
path: [...path, { kind: "type", type: type.type, name: type.name }],
|
|
1098
|
+
problems: type._problems || []
|
|
710
1099
|
}
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
value
|
|
732
|
-
};
|
|
1100
|
+
];
|
|
1101
|
+
}
|
|
1102
|
+
function getTypeProblems(type, path = []) {
|
|
1103
|
+
switch (type.type) {
|
|
1104
|
+
case "object":
|
|
1105
|
+
return getObjectProblems(type, path);
|
|
1106
|
+
case "document":
|
|
1107
|
+
return getObjectProblems(type, path);
|
|
1108
|
+
case "array":
|
|
1109
|
+
return getArrayProblems(type, path);
|
|
1110
|
+
case "reference":
|
|
1111
|
+
return getReferenceProblems(type, path);
|
|
1112
|
+
case "block":
|
|
1113
|
+
return getBlockProblems(type, path);
|
|
1114
|
+
case "image":
|
|
1115
|
+
return getImageProblems(type, path);
|
|
1116
|
+
case "file":
|
|
1117
|
+
return getFileProblems(type, path);
|
|
1118
|
+
default:
|
|
1119
|
+
return getDefaultProblems(type, path);
|
|
733
1120
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
return createArray(schemaType);
|
|
753
|
-
if (isObjectType(schemaType))
|
|
754
|
-
return createObject(schemaType);
|
|
755
|
-
if (lastType(schemaType)?.name === "document") {
|
|
756
|
-
const doc = documentTypes.get(schemaType.name);
|
|
757
|
-
return doc === void 0 ? { type: "unknown" } : { type: "object", attributes: doc?.attributes };
|
|
758
|
-
}
|
|
759
|
-
throw new Error(`Type "${schemaType.name}" not found`);
|
|
1121
|
+
}
|
|
1122
|
+
function getDupes(array2, selector = (v) => v) {
|
|
1123
|
+
const dupes = array2.reduce((acc, item) => {
|
|
1124
|
+
const key = selector(item);
|
|
1125
|
+
return acc[key] || (acc[key] = []), acc[key].push(item), acc;
|
|
1126
|
+
}, {});
|
|
1127
|
+
return Object.keys(dupes).map((key) => dupes[key].length > 1 ? dupes[key] : null).filter(Boolean);
|
|
1128
|
+
}
|
|
1129
|
+
const NOOP_VISITOR = (typeDef) => typeDef, TYPE_TYPE = { name: "type", type: null }, FUTURE_RESERVED = ["any", "time", "date"];
|
|
1130
|
+
function traverseSchema(types = [], coreTypes2 = [], visitor = NOOP_VISITOR) {
|
|
1131
|
+
const coreTypesRegistry = /* @__PURE__ */ Object.create(null), registry = /* @__PURE__ */ Object.create(null), coreTypeNames2 = coreTypes2.map((typeDef) => typeDef.name), reservedTypeNames = FUTURE_RESERVED.concat(coreTypeNames2), typeNames = types.map((typeDef) => typeDef && typeDef.name).filter(Boolean);
|
|
1132
|
+
coreTypes2.forEach((coreType) => {
|
|
1133
|
+
coreTypesRegistry[coreType.name] = coreType;
|
|
1134
|
+
}), types.forEach((type, i) => {
|
|
1135
|
+
registry[type && type.name || `__unnamed_${i}`] = {};
|
|
1136
|
+
});
|
|
1137
|
+
function getType(typeName) {
|
|
1138
|
+
return typeName === "type" ? TYPE_TYPE : coreTypesRegistry[typeName] || registry[typeName] || null;
|
|
760
1139
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
const fieldIsRequired = isFieldRequired(field), value = convertSchemaType(field.type);
|
|
765
|
-
if (value === null)
|
|
766
|
-
continue;
|
|
767
|
-
hasAssetRequired(field) && value.type === "object" && (value.attributes.asset.optional = !1);
|
|
768
|
-
const optional = extractOptions.enforceRequiredFields ? fieldIsRequired === !1 : !0;
|
|
769
|
-
attributes[field.name] = {
|
|
770
|
-
type: "objectAttribute",
|
|
771
|
-
value,
|
|
772
|
-
optional
|
|
773
|
-
};
|
|
774
|
-
}
|
|
775
|
-
return Object.keys(attributes).length === 0 ? { type: "unknown" } : (schemaType.type?.name !== "document" && schemaType.name !== "object" && (attributes._type = {
|
|
776
|
-
type: "objectAttribute",
|
|
777
|
-
value: {
|
|
778
|
-
type: "string",
|
|
779
|
-
value: schemaType.name
|
|
780
|
-
}
|
|
781
|
-
}), {
|
|
782
|
-
type: "object",
|
|
783
|
-
attributes
|
|
784
|
-
});
|
|
1140
|
+
const duplicateNames = uniq(flatten(getDupes(typeNames)));
|
|
1141
|
+
function isDuplicate(typeName) {
|
|
1142
|
+
return duplicateNames.includes(typeName);
|
|
785
1143
|
}
|
|
786
|
-
function
|
|
787
|
-
|
|
788
|
-
for (const item of arraySchemaType.of) {
|
|
789
|
-
const field = convertSchemaType(item);
|
|
790
|
-
field.type === "inline" ? of.push({
|
|
791
|
-
type: "object",
|
|
792
|
-
attributes: {
|
|
793
|
-
_key: createKeyField()
|
|
794
|
-
},
|
|
795
|
-
rest: field
|
|
796
|
-
}) : (field.type === "object" && (field.rest = {
|
|
797
|
-
type: "object",
|
|
798
|
-
attributes: {
|
|
799
|
-
_key: createKeyField()
|
|
800
|
-
}
|
|
801
|
-
}), of.push(field));
|
|
802
|
-
}
|
|
803
|
-
return of.length === 0 ? { type: "null" } : {
|
|
804
|
-
type: "array",
|
|
805
|
-
of: of.length > 1 ? {
|
|
806
|
-
type: "union",
|
|
807
|
-
of
|
|
808
|
-
} : of[0]
|
|
809
|
-
};
|
|
1144
|
+
function getTypeNames() {
|
|
1145
|
+
return typeNames.concat(coreTypeNames2);
|
|
810
1146
|
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
function createKeyField() {
|
|
814
|
-
return {
|
|
815
|
-
type: "objectAttribute",
|
|
816
|
-
value: {
|
|
817
|
-
type: "string"
|
|
818
|
-
}
|
|
819
|
-
};
|
|
820
|
-
}
|
|
821
|
-
function isFieldRequired(field) {
|
|
822
|
-
const { validation } = field.type;
|
|
823
|
-
if (!validation)
|
|
824
|
-
return !1;
|
|
825
|
-
const rules = Array.isArray(validation) ? validation : [validation];
|
|
826
|
-
for (const rule of rules) {
|
|
827
|
-
let required = !1;
|
|
828
|
-
const proxy = new Proxy(
|
|
829
|
-
{},
|
|
830
|
-
{
|
|
831
|
-
get: (target, methodName) => () => (methodName === "required" && (required = !0), proxy)
|
|
832
|
-
}
|
|
833
|
-
);
|
|
834
|
-
if (typeof rule == "function" && (rule(proxy), required) || typeof rule == "object" && rule !== null && "_required" in rule && rule._required === "required")
|
|
835
|
-
return !0;
|
|
1147
|
+
function isReserved(typeName) {
|
|
1148
|
+
return typeName === "type" || reservedTypeNames.includes(typeName);
|
|
836
1149
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
}
|
|
1150
|
+
const visitType = (isRoot) => (typeDef, index) => visitor(typeDef, {
|
|
1151
|
+
visit: visitType(!1),
|
|
1152
|
+
isRoot,
|
|
1153
|
+
getType,
|
|
1154
|
+
getTypeNames,
|
|
1155
|
+
isReserved,
|
|
1156
|
+
isDuplicate,
|
|
1157
|
+
index
|
|
1158
|
+
});
|
|
1159
|
+
return coreTypes2.forEach((coreTypeDef) => {
|
|
1160
|
+
Object.assign(coreTypesRegistry[coreTypeDef.name], visitType(coreTypeDef));
|
|
1161
|
+
}), types.forEach((typeDef, i) => {
|
|
1162
|
+
Object.assign(
|
|
1163
|
+
registry[typeDef && typeDef.name || `__unnamed_${i}`],
|
|
1164
|
+
visitType(!0)(typeDef, i)
|
|
851
1165
|
);
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
}
|
|
872
|
-
function isStringType(typeDef) {
|
|
873
|
-
return isType(typeDef, "string");
|
|
874
|
-
}
|
|
875
|
-
function isNumberType(typeDef) {
|
|
876
|
-
return isType(typeDef, "number");
|
|
877
|
-
}
|
|
878
|
-
function createStringTypeNodeDefintion(stringSchemaType) {
|
|
879
|
-
const listOptions = stringSchemaType.options?.list;
|
|
880
|
-
return listOptions && Array.isArray(listOptions) ? {
|
|
881
|
-
type: "union",
|
|
882
|
-
of: listOptions.map((v) => ({
|
|
883
|
-
type: "string",
|
|
884
|
-
value: typeof v == "string" ? v : v.value
|
|
885
|
-
}))
|
|
886
|
-
} : {
|
|
887
|
-
type: "string"
|
|
1166
|
+
}), {
|
|
1167
|
+
get(typeName) {
|
|
1168
|
+
const res = registry[typeName] || coreTypesRegistry[typeName];
|
|
1169
|
+
if (res)
|
|
1170
|
+
return res;
|
|
1171
|
+
throw new Error(`No such type: ${typeName}`);
|
|
1172
|
+
},
|
|
1173
|
+
has(typeName) {
|
|
1174
|
+
return typeName in registry || typeName in coreTypesRegistry;
|
|
1175
|
+
},
|
|
1176
|
+
getTypeNames() {
|
|
1177
|
+
return Object.keys(registry);
|
|
1178
|
+
},
|
|
1179
|
+
getTypes() {
|
|
1180
|
+
return this.getTypeNames().map(this.get);
|
|
1181
|
+
},
|
|
1182
|
+
toJSON() {
|
|
1183
|
+
return this.getTypes();
|
|
1184
|
+
}
|
|
888
1185
|
};
|
|
889
1186
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
}
|
|
1187
|
+
const coreTypes = [
|
|
1188
|
+
{ name: "array", jsonType: "array", type: "type" },
|
|
1189
|
+
{ name: "block", jsonType: "object", type: "type" },
|
|
1190
|
+
{ name: "boolean", jsonType: "boolean", type: "type" },
|
|
1191
|
+
{ name: "datetime", jsonType: "string", type: "type" },
|
|
1192
|
+
{ name: "date", jsonType: "string", type: "type" },
|
|
1193
|
+
{ name: "document", jsonType: "object", type: "type" },
|
|
1194
|
+
{ name: "email", jsonType: "string", type: "type" },
|
|
1195
|
+
{ name: "file", jsonType: "object", type: "type" },
|
|
1196
|
+
{ name: "geopoint", jsonType: "object", type: "type" },
|
|
1197
|
+
{ name: "image", jsonType: "object", type: "type" },
|
|
1198
|
+
{ name: "number", jsonType: "number", type: "type" },
|
|
1199
|
+
{ name: "object", jsonType: "object", type: "type" },
|
|
1200
|
+
{ name: "reference", jsonType: "object", type: "type" },
|
|
1201
|
+
{ name: "crossDatasetReference", jsonType: "object", type: "type" },
|
|
1202
|
+
{ name: "globalDocumentReference", jsonType: "object", type: "type" },
|
|
1203
|
+
{ name: "slug", jsonType: "object", type: "type" },
|
|
1204
|
+
{ name: "span", jsonType: "object", type: "type" },
|
|
1205
|
+
{ name: "string", jsonType: "string", type: "type" },
|
|
1206
|
+
{ name: "telephone", jsonType: "string", type: "type" },
|
|
1207
|
+
{ name: "text", jsonType: "string", type: "type" },
|
|
1208
|
+
{ name: "url", jsonType: "string", type: "type" }
|
|
1209
|
+
], coreTypeNames = coreTypes.map((t) => t.name);
|
|
1210
|
+
function traverseSanitySchema(schemaTypes, visitor) {
|
|
1211
|
+
return traverseSchema(schemaTypes, coreTypes, visitor);
|
|
901
1212
|
}
|
|
902
|
-
function
|
|
903
|
-
|
|
904
|
-
return references.length === 1 ? groqJs.createReferenceTypeNode(references[0]) : {
|
|
905
|
-
type: "union",
|
|
906
|
-
of: references.map((name) => groqJs.createReferenceTypeNode(name))
|
|
907
|
-
};
|
|
1213
|
+
function isPrimitiveTypeName(typeName) {
|
|
1214
|
+
return typeName === "string" || typeName === "number" || typeName === "boolean";
|
|
908
1215
|
}
|
|
909
|
-
function
|
|
910
|
-
|
|
911
|
-
return [...new Set(allReferences.map((ref) => ref.name))];
|
|
1216
|
+
function isAssignable(typeName, type) {
|
|
1217
|
+
return (typeof type.name == "string" ? type.name : type.type) === typeName;
|
|
912
1218
|
}
|
|
913
|
-
function
|
|
914
|
-
|
|
915
|
-
return "type" in type && isReferenceType(type.type) ? [...gatherReferenceTypes(type.type), ...refTo] : refTo;
|
|
1219
|
+
function quote$2(n) {
|
|
1220
|
+
return `"${n}"`;
|
|
916
1221
|
}
|
|
917
|
-
function
|
|
918
|
-
return
|
|
919
|
-
}
|
|
920
|
-
function isType(typeDef, typeName) {
|
|
921
|
-
let type = typeDef;
|
|
922
|
-
for (; type; ) {
|
|
923
|
-
if (type.name === typeName || type.type && type.type.name === typeName)
|
|
924
|
-
return !0;
|
|
925
|
-
type = type.type;
|
|
926
|
-
}
|
|
927
|
-
return !1;
|
|
928
|
-
}
|
|
929
|
-
function lastType(typeDef) {
|
|
930
|
-
let type = typeDef;
|
|
931
|
-
for (; type; ) {
|
|
932
|
-
if (!type.type)
|
|
933
|
-
return type;
|
|
934
|
-
type = type.type;
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
function sortByDependencies(compiledSchema) {
|
|
938
|
-
const seen = /* @__PURE__ */ new Set();
|
|
939
|
-
function walkDependencies(schemaType, dependencies) {
|
|
940
|
-
if (!seen.has(schemaType)) {
|
|
941
|
-
if (seen.add(schemaType), "fields" in schemaType)
|
|
942
|
-
for (const field of gatherFields(schemaType)) {
|
|
943
|
-
const last = lastType(field.type);
|
|
944
|
-
if (last.name === "document") {
|
|
945
|
-
dependencies.add(last);
|
|
946
|
-
continue;
|
|
947
|
-
}
|
|
948
|
-
let schemaTypeName;
|
|
949
|
-
schemaType.type.type ? schemaTypeName = field.type.type.name : "jsonType" in schemaType.type && (schemaTypeName = field.type.jsonType), (schemaTypeName === "object" || schemaTypeName === "block") && (isReferenceType(field.type) ? field.type.to.forEach((ref) => dependencies.add(ref.type)) : dependencies.add(field.type)), walkDependencies(field.type, dependencies);
|
|
950
|
-
}
|
|
951
|
-
else if ("of" in schemaType)
|
|
952
|
-
for (const item of schemaType.of)
|
|
953
|
-
walkDependencies(item, dependencies);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
const dependencyMap = /* @__PURE__ */ new Map();
|
|
957
|
-
compiledSchema.getTypeNames().forEach((typeName) => {
|
|
958
|
-
const schemaType = compiledSchema.get(typeName);
|
|
959
|
-
if (schemaType === void 0 || schemaType.type === null)
|
|
960
|
-
return;
|
|
961
|
-
const dependencies = /* @__PURE__ */ new Set();
|
|
962
|
-
walkDependencies(schemaType, dependencies), dependencyMap.set(schemaType, dependencies), seen.clear();
|
|
963
|
-
});
|
|
964
|
-
const typeNames = [], currentlyVisiting = /* @__PURE__ */ new Set(), visited = /* @__PURE__ */ new Set();
|
|
965
|
-
function visit(type) {
|
|
966
|
-
if (visited.has(type) || currentlyVisiting.has(type))
|
|
967
|
-
return;
|
|
968
|
-
currentlyVisiting.add(type);
|
|
969
|
-
const deps = dependencyMap.get(type);
|
|
970
|
-
deps !== void 0 && deps.forEach((dep) => visit(dep)), currentlyVisiting.delete(type), visited.add(type), typeNames.includes(type.name) || typeNames.unshift(type.name);
|
|
971
|
-
}
|
|
972
|
-
for (const [type] of dependencyMap)
|
|
973
|
-
visit(type);
|
|
974
|
-
return typeNames;
|
|
975
|
-
}
|
|
976
|
-
const HELP_IDS = {
|
|
977
|
-
TYPE_INVALID: "schema-type-invalid",
|
|
978
|
-
TYPE_IS_ESM_MODULE: "schema-type-is-esm-module",
|
|
979
|
-
TYPE_NAME_RESERVED: "schema-type-name-reserved",
|
|
980
|
-
TYPE_MISSING_NAME: "schema-type-missing-name-or-type",
|
|
981
|
-
TYPE_MISSING_TYPE: "schema-type-missing-name-or-type",
|
|
982
|
-
TYPE_TITLE_RECOMMENDED: "schema-type-title-is-recommended",
|
|
983
|
-
TYPE_TITLE_INVALID: "schema-type-title-is-recommended",
|
|
984
|
-
OBJECT_FIELDS_INVALID: "schema-object-fields-invalid",
|
|
985
|
-
OBJECT_FIELD_NOT_UNIQUE: "schema-object-fields-invalid",
|
|
986
|
-
OBJECT_FIELD_NAME_INVALID: "schema-object-fields-invalid",
|
|
987
|
-
OBJECT_FIELD_DEFINITION_INVALID_TYPE: "schema-object-fields-invalid",
|
|
988
|
-
ARRAY_PREDEFINED_CHOICES_INVALID: "schema-predefined-choices-invalid",
|
|
989
|
-
ARRAY_OF_ARRAY: "schema-array-of-array",
|
|
990
|
-
ARRAY_OF_INVALID: "schema-array-of-invalid",
|
|
991
|
-
ARRAY_OF_NOT_UNIQUE: "schema-array-of-invalid",
|
|
992
|
-
ARRAY_OF_TYPE_GLOBAL_TYPE_CONFLICT: "schema-array-of-type-global-type-conflict",
|
|
993
|
-
ARRAY_OF_TYPE_BUILTIN_TYPE_CONFLICT: "schema-array-of-type-builtin-type-conflict",
|
|
994
|
-
REFERENCE_TO_INVALID: "schema-reference-to-invalid",
|
|
995
|
-
REFERENCE_TO_NOT_UNIQUE: "schema-reference-to-invalid",
|
|
996
|
-
REFERENCE_INVALID_OPTIONS: "schema-reference-invalid-options",
|
|
997
|
-
REFERENCE_INVALID_OPTIONS_LOCATION: "schema-reference-options-nesting",
|
|
998
|
-
REFERENCE_INVALID_FILTER_PARAMS_COMBINATION: "schema-reference-filter-params-combination",
|
|
999
|
-
SLUG_SLUGIFY_FN_RENAMED: "slug-slugifyfn-renamed",
|
|
1000
|
-
ASSET_METADATA_FIELD_INVALID: "asset-metadata-field-invalid",
|
|
1001
|
-
CROSS_DATASET_REFERENCE_INVALID: "cross-dataset-reference-invalid",
|
|
1002
|
-
GLOBAL_DOCUMENT_REFERENCE_INVALID: "global-document-reference-invalid",
|
|
1003
|
-
DEPRECATED_BLOCKEDITOR_KEY: "schema-deprecated-blockeditor-key",
|
|
1004
|
-
STANDALONE_BLOCK_TYPE: "schema-standalone-block-type"
|
|
1005
|
-
};
|
|
1006
|
-
function createValidationResult(severity, message, helpId) {
|
|
1007
|
-
if (helpId && !Object.keys(HELP_IDS).some((id) => HELP_IDS[id] === helpId))
|
|
1008
|
-
throw new Error(
|
|
1009
|
-
`Used the unknown helpId "${helpId}", please add it to the array in createValidationResult.js`
|
|
1010
|
-
);
|
|
1011
|
-
return {
|
|
1012
|
-
severity,
|
|
1013
|
-
message,
|
|
1014
|
-
helpId
|
|
1015
|
-
};
|
|
1016
|
-
}
|
|
1017
|
-
const error = (message, helpId) => createValidationResult("error", message, helpId), warning = (message, helpId) => createValidationResult("warning", message, helpId);
|
|
1018
|
-
function groupProblems(types) {
|
|
1019
|
-
return flatten__default.default(types.map((type) => getTypeProblems(type))).filter(
|
|
1020
|
-
(type) => type.problems.length > 0
|
|
1021
|
-
);
|
|
1022
|
-
}
|
|
1023
|
-
function createTypeWithMembersProblemsAccessor(memberPropertyName, getMembers = (type) => get__default.default(type, memberPropertyName)) {
|
|
1024
|
-
return function(type, parentPath) {
|
|
1025
|
-
const currentPath = [
|
|
1026
|
-
...parentPath,
|
|
1027
|
-
{ kind: "type", type: type.type, name: type.name }
|
|
1028
|
-
], members = getMembers(type) || [], memberProblems = Array.isArray(members) ? members.map((memberType) => {
|
|
1029
|
-
const propertySegment = {
|
|
1030
|
-
kind: "property",
|
|
1031
|
-
name: memberPropertyName
|
|
1032
|
-
}, memberPath = [...currentPath, propertySegment];
|
|
1033
|
-
return getTypeProblems(memberType, memberPath);
|
|
1034
|
-
}) : [
|
|
1035
|
-
[
|
|
1036
|
-
{
|
|
1037
|
-
path: currentPath,
|
|
1038
|
-
problems: [error(`Member declaration (${memberPropertyName}) is not an array`)]
|
|
1039
|
-
}
|
|
1040
|
-
]
|
|
1041
|
-
];
|
|
1042
|
-
return [
|
|
1043
|
-
{
|
|
1044
|
-
path: currentPath,
|
|
1045
|
-
problems: type._problems || []
|
|
1046
|
-
},
|
|
1047
|
-
...flatten__default.default(memberProblems)
|
|
1048
|
-
];
|
|
1049
|
-
};
|
|
1050
|
-
}
|
|
1051
|
-
const arrify = (val) => Array.isArray(val) ? val : typeof val > "u" && [] || [val], getObjectProblems = createTypeWithMembersProblemsAccessor("fields"), getImageProblems = createTypeWithMembersProblemsAccessor("fields"), getFileProblems = createTypeWithMembersProblemsAccessor("fields"), getArrayProblems = createTypeWithMembersProblemsAccessor("of"), getReferenceProblems = createTypeWithMembersProblemsAccessor(
|
|
1052
|
-
"to",
|
|
1053
|
-
(type) => "to" in type ? arrify(type.to) : []
|
|
1054
|
-
), getBlockAnnotationProblems = createTypeWithMembersProblemsAccessor("marks.annotations"), getBlockMemberProblems = createTypeWithMembersProblemsAccessor("of"), getBlockProblems = (type, problems) => [
|
|
1055
|
-
...getBlockAnnotationProblems(type, problems),
|
|
1056
|
-
...getBlockMemberProblems(type, problems)
|
|
1057
|
-
];
|
|
1058
|
-
function getDefaultProblems(type, path = []) {
|
|
1059
|
-
return [
|
|
1060
|
-
{
|
|
1061
|
-
path: [...path, { kind: "type", type: type.type, name: type.name }],
|
|
1062
|
-
problems: type._problems || []
|
|
1063
|
-
}
|
|
1064
|
-
];
|
|
1065
|
-
}
|
|
1066
|
-
function getTypeProblems(type, path = []) {
|
|
1067
|
-
switch (type.type) {
|
|
1068
|
-
case "object":
|
|
1069
|
-
return getObjectProblems(type, path);
|
|
1070
|
-
case "document":
|
|
1071
|
-
return getObjectProblems(type, path);
|
|
1072
|
-
case "array":
|
|
1073
|
-
return getArrayProblems(type, path);
|
|
1074
|
-
case "reference":
|
|
1075
|
-
return getReferenceProblems(type, path);
|
|
1076
|
-
case "block":
|
|
1077
|
-
return getBlockProblems(type, path);
|
|
1078
|
-
case "image":
|
|
1079
|
-
return getImageProblems(type, path);
|
|
1080
|
-
case "file":
|
|
1081
|
-
return getFileProblems(type, path);
|
|
1082
|
-
default:
|
|
1083
|
-
return getDefaultProblems(type, path);
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
function getDupes(array2, selector = (v) => v) {
|
|
1087
|
-
const dupes = array2.reduce((acc, item) => {
|
|
1088
|
-
const key = selector(item);
|
|
1089
|
-
return acc[key] || (acc[key] = []), acc[key].push(item), acc;
|
|
1090
|
-
}, {});
|
|
1091
|
-
return Object.keys(dupes).map((key) => dupes[key].length > 1 ? dupes[key] : null).filter(Boolean);
|
|
1092
|
-
}
|
|
1093
|
-
const NOOP_VISITOR = (typeDef) => typeDef, TYPE_TYPE = { name: "type", type: null }, FUTURE_RESERVED = ["any", "time", "date"];
|
|
1094
|
-
function traverseSchema(types = [], coreTypes2 = [], visitor = NOOP_VISITOR) {
|
|
1095
|
-
const coreTypesRegistry = /* @__PURE__ */ Object.create(null), registry = /* @__PURE__ */ Object.create(null), coreTypeNames2 = coreTypes2.map((typeDef) => typeDef.name), reservedTypeNames = FUTURE_RESERVED.concat(coreTypeNames2), typeNames = types.map((typeDef) => typeDef && typeDef.name).filter(Boolean);
|
|
1096
|
-
coreTypes2.forEach((coreType) => {
|
|
1097
|
-
coreTypesRegistry[coreType.name] = coreType;
|
|
1098
|
-
}), types.forEach((type, i) => {
|
|
1099
|
-
registry[type && type.name || `__unnamed_${i}`] = {};
|
|
1100
|
-
});
|
|
1101
|
-
function getType(typeName) {
|
|
1102
|
-
return typeName === "type" ? TYPE_TYPE : coreTypesRegistry[typeName] || registry[typeName] || null;
|
|
1103
|
-
}
|
|
1104
|
-
const duplicateNames = uniq__default.default(flatten__default.default(getDupes(typeNames)));
|
|
1105
|
-
function isDuplicate(typeName) {
|
|
1106
|
-
return duplicateNames.includes(typeName);
|
|
1107
|
-
}
|
|
1108
|
-
function getTypeNames() {
|
|
1109
|
-
return typeNames.concat(coreTypeNames2);
|
|
1110
|
-
}
|
|
1111
|
-
function isReserved(typeName) {
|
|
1112
|
-
return typeName === "type" || reservedTypeNames.includes(typeName);
|
|
1113
|
-
}
|
|
1114
|
-
const visitType = (isRoot) => (typeDef, index) => visitor(typeDef, {
|
|
1115
|
-
visit: visitType(!1),
|
|
1116
|
-
isRoot,
|
|
1117
|
-
getType,
|
|
1118
|
-
getTypeNames,
|
|
1119
|
-
isReserved,
|
|
1120
|
-
isDuplicate,
|
|
1121
|
-
index
|
|
1122
|
-
});
|
|
1123
|
-
return coreTypes2.forEach((coreTypeDef) => {
|
|
1124
|
-
Object.assign(coreTypesRegistry[coreTypeDef.name], visitType(coreTypeDef));
|
|
1125
|
-
}), types.forEach((typeDef, i) => {
|
|
1126
|
-
Object.assign(
|
|
1127
|
-
registry[typeDef && typeDef.name || `__unnamed_${i}`],
|
|
1128
|
-
visitType(!0)(typeDef, i)
|
|
1129
|
-
);
|
|
1130
|
-
}), {
|
|
1131
|
-
get(typeName) {
|
|
1132
|
-
const res = registry[typeName] || coreTypesRegistry[typeName];
|
|
1133
|
-
if (res)
|
|
1134
|
-
return res;
|
|
1135
|
-
throw new Error(`No such type: ${typeName}`);
|
|
1136
|
-
},
|
|
1137
|
-
has(typeName) {
|
|
1138
|
-
return typeName in registry || typeName in coreTypesRegistry;
|
|
1139
|
-
},
|
|
1140
|
-
getTypeNames() {
|
|
1141
|
-
return Object.keys(registry);
|
|
1142
|
-
},
|
|
1143
|
-
getTypes() {
|
|
1144
|
-
return this.getTypeNames().map(this.get);
|
|
1145
|
-
},
|
|
1146
|
-
toJSON() {
|
|
1147
|
-
return this.getTypes();
|
|
1148
|
-
}
|
|
1149
|
-
};
|
|
1150
|
-
}
|
|
1151
|
-
const coreTypes = [
|
|
1152
|
-
{ name: "array", jsonType: "array", type: "type" },
|
|
1153
|
-
{ name: "block", jsonType: "object", type: "type" },
|
|
1154
|
-
{ name: "boolean", jsonType: "boolean", type: "type" },
|
|
1155
|
-
{ name: "datetime", jsonType: "string", type: "type" },
|
|
1156
|
-
{ name: "date", jsonType: "string", type: "type" },
|
|
1157
|
-
{ name: "document", jsonType: "object", type: "type" },
|
|
1158
|
-
{ name: "email", jsonType: "string", type: "type" },
|
|
1159
|
-
{ name: "file", jsonType: "object", type: "type" },
|
|
1160
|
-
{ name: "geopoint", jsonType: "object", type: "type" },
|
|
1161
|
-
{ name: "image", jsonType: "object", type: "type" },
|
|
1162
|
-
{ name: "number", jsonType: "number", type: "type" },
|
|
1163
|
-
{ name: "object", jsonType: "object", type: "type" },
|
|
1164
|
-
{ name: "reference", jsonType: "object", type: "type" },
|
|
1165
|
-
{ name: "crossDatasetReference", jsonType: "object", type: "type" },
|
|
1166
|
-
{ name: "globalDocumentReference", jsonType: "object", type: "type" },
|
|
1167
|
-
{ name: "slug", jsonType: "object", type: "type" },
|
|
1168
|
-
{ name: "span", jsonType: "object", type: "type" },
|
|
1169
|
-
{ name: "string", jsonType: "string", type: "type" },
|
|
1170
|
-
{ name: "telephone", jsonType: "string", type: "type" },
|
|
1171
|
-
{ name: "text", jsonType: "string", type: "type" },
|
|
1172
|
-
{ name: "url", jsonType: "string", type: "type" }
|
|
1173
|
-
], coreTypeNames = coreTypes.map((t) => t.name);
|
|
1174
|
-
function traverseSanitySchema(schemaTypes, visitor) {
|
|
1175
|
-
return traverseSchema(schemaTypes, coreTypes, visitor);
|
|
1176
|
-
}
|
|
1177
|
-
function isPrimitiveTypeName(typeName) {
|
|
1178
|
-
return typeName === "string" || typeName === "number" || typeName === "boolean";
|
|
1179
|
-
}
|
|
1180
|
-
function isAssignable(typeName, type) {
|
|
1181
|
-
return (typeof type.name == "string" ? type.name : type.type) === typeName;
|
|
1182
|
-
}
|
|
1183
|
-
function quote$2(n) {
|
|
1184
|
-
return `"${n}"`;
|
|
1185
|
-
}
|
|
1186
|
-
function pluralize(arr, suf = "s") {
|
|
1187
|
-
return arr.length === 1 ? "" : suf;
|
|
1222
|
+
function pluralize(arr, suf = "s") {
|
|
1223
|
+
return arr.length === 1 ? "" : suf;
|
|
1188
1224
|
}
|
|
1189
1225
|
function format(value) {
|
|
1190
|
-
return Array.isArray(value) ? `array with ${value.length} entries` : typeof value == "object" && value !== null ? `object with keys ${
|
|
1226
|
+
return Array.isArray(value) ? `array with ${value.length} entries` : typeof value == "object" && value !== null ? `object with keys ${humanizeList(Object.keys(value).map(quote$2))}` : quote$2(value);
|
|
1191
1227
|
}
|
|
1192
1228
|
var array = (typeDef, visitorContext) => {
|
|
1193
1229
|
const ofIsArray = Array.isArray(typeDef.of);
|
|
@@ -1233,7 +1269,7 @@ var array = (typeDef, visitorContext) => {
|
|
|
1233
1269
|
_problems: invalid
|
|
1234
1270
|
};
|
|
1235
1271
|
}
|
|
1236
|
-
const problems =
|
|
1272
|
+
const problems = flatten([
|
|
1237
1273
|
ofIsArray ? getDupes(typeDef.of, (t) => `${t.name};${t.type}`).map(
|
|
1238
1274
|
(dupes) => error(
|
|
1239
1275
|
`Found ${dupes.length} members with same type, but not unique names "${dupes[0].type}" in array. This makes it impossible to tell their values apart and you should consider naming them`,
|
|
@@ -1252,7 +1288,7 @@ var array = (typeDef, visitorContext) => {
|
|
|
1252
1288
|
HELP_IDS.ARRAY_OF_INVALID
|
|
1253
1289
|
)
|
|
1254
1290
|
);
|
|
1255
|
-
const [primitiveTypes, objectTypes] =
|
|
1291
|
+
const [primitiveTypes, objectTypes] = partition(
|
|
1256
1292
|
of,
|
|
1257
1293
|
(ofType) => isPrimitiveTypeName(ofType.type) || isPrimitiveTypeName(visitorContext.getType(ofType.type)?.jsonType)
|
|
1258
1294
|
), isMixedArray = primitiveTypes.length > 0 && objectTypes.length > 0;
|
|
@@ -1262,9 +1298,9 @@ var array = (typeDef, visitorContext) => {
|
|
|
1262
1298
|
error(
|
|
1263
1299
|
`The array type's 'of' property can't have both object types and primitive types (found primitive type ${pluralize(
|
|
1264
1300
|
primitiveTypeNames
|
|
1265
|
-
)} ${
|
|
1301
|
+
)} ${humanizeList(primitiveTypeNames.map(quote$2))} and object type${pluralize(
|
|
1266
1302
|
objectTypeNames
|
|
1267
|
-
)} ${
|
|
1303
|
+
)} ${humanizeList(objectTypeNames.map(quote$2))})`,
|
|
1268
1304
|
HELP_IDS.ARRAY_OF_INVALID
|
|
1269
1305
|
)
|
|
1270
1306
|
);
|
|
@@ -1273,7 +1309,7 @@ var array = (typeDef, visitorContext) => {
|
|
|
1273
1309
|
return !isMixedArray && Array.isArray(list) && (primitiveTypes.length > 0 ? list.forEach((option) => {
|
|
1274
1310
|
const value = option?.value ?? option;
|
|
1275
1311
|
if (!primitiveTypes.some((primitiveType) => typeof value === visitorContext.getType(primitiveType.type).jsonType)) {
|
|
1276
|
-
const formattedTypeList =
|
|
1312
|
+
const formattedTypeList = humanizeList(
|
|
1277
1313
|
primitiveTypes.map((t) => t.name || t.type),
|
|
1278
1314
|
{ conjunction: "or" }
|
|
1279
1315
|
);
|
|
@@ -1294,7 +1330,7 @@ var array = (typeDef, visitorContext) => {
|
|
|
1294
1330
|
error(
|
|
1295
1331
|
`An invalid entry found in options.list: ${format(
|
|
1296
1332
|
option
|
|
1297
|
-
)}. Must be an object with "_type" set to ${
|
|
1333
|
+
)}. Must be an object with "_type" set to ${humanizeList(
|
|
1298
1334
|
objectTypes.map((t) => t.name || t.type).map((t) => t === "object" ? "undefined" : quote$2(t)),
|
|
1299
1335
|
{ conjunction: "or" }
|
|
1300
1336
|
)}`,
|
|
@@ -1346,12 +1382,12 @@ function validateBlockType(typeDef, visitorContext) {
|
|
|
1346
1382
|
);
|
|
1347
1383
|
return disallowedKeys.length > 0 && problems.push(
|
|
1348
1384
|
error(
|
|
1349
|
-
`Found unknown properties for block declaration: ${
|
|
1385
|
+
`Found unknown properties for block declaration: ${humanizeList(
|
|
1350
1386
|
disallowedKeys.map(quote$1)
|
|
1351
1387
|
)}`
|
|
1352
1388
|
)
|
|
1353
1389
|
), marks && (marks = validateMarks(typeDef.marks, visitorContext, problems)), styles && (styles = validateStyles(styles, visitorContext, problems)), lists && (lists = validateLists(lists, visitorContext, problems)), members && (members = validateMembers(members, visitorContext, problems)), {
|
|
1354
|
-
...
|
|
1390
|
+
...omit(typeDef, disallowedKeys),
|
|
1355
1391
|
marks,
|
|
1356
1392
|
styles,
|
|
1357
1393
|
name: typeDef.name || typeDef.type,
|
|
@@ -1361,14 +1397,14 @@ function validateBlockType(typeDef, visitorContext) {
|
|
|
1361
1397
|
}
|
|
1362
1398
|
function validateMarks(marks, visitorContext, problems) {
|
|
1363
1399
|
let decorators = marks.decorators, annotations = marks.annotations;
|
|
1364
|
-
if (!
|
|
1400
|
+
if (!isPlainObject(marks))
|
|
1365
1401
|
return problems.push(error(`"marks" declaration should be an object, got ${getTypeOf(marks)}`)), problems;
|
|
1366
1402
|
const disallowedMarkKeys = Object.keys(marks).filter(
|
|
1367
1403
|
(key) => !allowedMarkKeys.includes(key) && !key.startsWith("_")
|
|
1368
1404
|
);
|
|
1369
1405
|
return disallowedMarkKeys.length > 0 && problems.push(
|
|
1370
1406
|
error(
|
|
1371
|
-
`Found unknown properties for block declaration: ${
|
|
1407
|
+
`Found unknown properties for block declaration: ${humanizeList(
|
|
1372
1408
|
disallowedMarkKeys.map(quote$1)
|
|
1373
1409
|
)}`
|
|
1374
1410
|
)
|
|
@@ -1382,7 +1418,7 @@ function validateMarks(marks, visitorContext, problems) {
|
|
|
1382
1418
|
}
|
|
1383
1419
|
function validateLists(lists, visitorContext, problems) {
|
|
1384
1420
|
return Array.isArray(lists) ? (lists.forEach((list, index) => {
|
|
1385
|
-
if (!
|
|
1421
|
+
if (!isPlainObject(list)) {
|
|
1386
1422
|
problems.push(error(`List must be an object, got ${getTypeOf(list)}`));
|
|
1387
1423
|
return;
|
|
1388
1424
|
}
|
|
@@ -1391,7 +1427,7 @@ function validateLists(lists, visitorContext, problems) {
|
|
|
1391
1427
|
);
|
|
1392
1428
|
disallowedKeys.length > 0 && problems.push(
|
|
1393
1429
|
error(
|
|
1394
|
-
`Found unknown properties for list ${name}: ${
|
|
1430
|
+
`Found unknown properties for list ${name}: ${humanizeList(disallowedKeys.map(quote$1))}`
|
|
1395
1431
|
)
|
|
1396
1432
|
), list.value ? typeof list.value != "string" ? problems.push(
|
|
1397
1433
|
error(
|
|
@@ -1404,7 +1440,7 @@ function validateLists(lists, visitorContext, problems) {
|
|
|
1404
1440
|
}
|
|
1405
1441
|
function validateStyles(styles, visitorContext, problems) {
|
|
1406
1442
|
return Array.isArray(styles) ? (styles.forEach((style, index) => {
|
|
1407
|
-
if (!
|
|
1443
|
+
if (!isPlainObject(style)) {
|
|
1408
1444
|
problems.push(error(`Style must be an object, got ${getTypeOf(style)}`));
|
|
1409
1445
|
return;
|
|
1410
1446
|
}
|
|
@@ -1413,7 +1449,7 @@ function validateStyles(styles, visitorContext, problems) {
|
|
|
1413
1449
|
);
|
|
1414
1450
|
disallowedKeys.length > 0 && problems.push(
|
|
1415
1451
|
error(
|
|
1416
|
-
`Found unknown properties for style ${name}: ${
|
|
1452
|
+
`Found unknown properties for style ${name}: ${humanizeList(disallowedKeys.map(quote$1))}`
|
|
1417
1453
|
)
|
|
1418
1454
|
), style.value ? typeof style.value != "string" ? problems.push(
|
|
1419
1455
|
error(
|
|
@@ -1431,7 +1467,7 @@ function validateStyles(styles, visitorContext, problems) {
|
|
|
1431
1467
|
}
|
|
1432
1468
|
function validateDecorators(decorators, visitorContext, problems) {
|
|
1433
1469
|
return decorators.forEach((decorator, index) => {
|
|
1434
|
-
if (!
|
|
1470
|
+
if (!isPlainObject(decorator)) {
|
|
1435
1471
|
problems.push(error(`Annotation must be an object, got ${getTypeOf(decorator)}`));
|
|
1436
1472
|
return;
|
|
1437
1473
|
}
|
|
@@ -1440,7 +1476,7 @@ function validateDecorators(decorators, visitorContext, problems) {
|
|
|
1440
1476
|
);
|
|
1441
1477
|
disallowedKeys.length > 0 && problems.push(
|
|
1442
1478
|
error(
|
|
1443
|
-
`Found unknown properties for decorator ${name}: ${
|
|
1479
|
+
`Found unknown properties for decorator ${name}: ${humanizeList(
|
|
1444
1480
|
disallowedKeys.map(quote$1)
|
|
1445
1481
|
)}`
|
|
1446
1482
|
)
|
|
@@ -1460,7 +1496,7 @@ function validateDecorators(decorators, visitorContext, problems) {
|
|
|
1460
1496
|
}
|
|
1461
1497
|
function validateAnnotations(annotations, visitorContext, problems) {
|
|
1462
1498
|
return annotations.map((annotation) => {
|
|
1463
|
-
if (!
|
|
1499
|
+
if (!isPlainObject(annotation))
|
|
1464
1500
|
return {
|
|
1465
1501
|
...annotation,
|
|
1466
1502
|
_problems: [error(`Annotation must be an object, got ${getTypeOf(annotation)}`)]
|
|
@@ -1537,7 +1573,7 @@ function validateTypeName(typeName, visitorContext) {
|
|
|
1537
1573
|
)
|
|
1538
1574
|
];
|
|
1539
1575
|
if (!possibleTypeNames.includes(typeName)) {
|
|
1540
|
-
const suggestions = possibleTypeNames.map((possibleTypeName) => [
|
|
1576
|
+
const suggestions = possibleTypeNames.map((possibleTypeName) => [leven(typeName, possibleTypeName), possibleTypeName]).filter(([distance]) => distance < 3).map(([_, name]) => name), suggestion = suggestions.length > 0 ? ` Did you mean ${humanizeList(suggestions.map(quote), { conjunction: "or" })}?` : "";
|
|
1541
1577
|
return [error(`Unknown type: ${typeName}.${suggestion}`)];
|
|
1542
1578
|
}
|
|
1543
1579
|
return [];
|
|
@@ -1574,7 +1610,7 @@ function isValidDatasetName(name) {
|
|
|
1574
1610
|
return name.length >= 2 && name.toLowerCase() === name && VALID_DATASET.test(name) || `The provided dataset "${name}" doesn't look like a valid dataset. Dataset names must be more than 2 characters, can only contain lowercase characters, numbers, underscores and dashes and can not start with a dash or an underscore`;
|
|
1575
1611
|
}
|
|
1576
1612
|
var crossDatasetReference = (typeDef, visitorContext) => {
|
|
1577
|
-
const isValidTo = Array.isArray(typeDef.to) ||
|
|
1613
|
+
const isValidTo = Array.isArray(typeDef.to) || isPlainObject(typeDef.to), normalizedTo = normalizeToProp$2(typeDef), problems = flatten([
|
|
1578
1614
|
isValidTo ? getDupes(normalizedTo, (t) => `${t.name};${t.type}`).map(
|
|
1579
1615
|
(dupes) => error(
|
|
1580
1616
|
`Found ${dupes.length} members with same type, but not unique names "${dupes[0].type}" in reference. This makes it impossible to tell their values apart and you should consider naming them`,
|
|
@@ -1596,7 +1632,7 @@ var crossDatasetReference = (typeDef, visitorContext) => {
|
|
|
1596
1632
|
`The referenced type at index ${index} must be named. Specify the name of the type you want to create references to.`,
|
|
1597
1633
|
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
1598
1634
|
)
|
|
1599
|
-
),
|
|
1635
|
+
), isPlainObject(crossDatasetTypeDef.preview) || problems.push(
|
|
1600
1636
|
error(
|
|
1601
1637
|
`Missing required preview config for the referenced type "${crossDatasetTypeDef.type || "<unknown type>"}"`,
|
|
1602
1638
|
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
@@ -1631,14 +1667,14 @@ function getOptionErrors$2(typeDef) {
|
|
|
1631
1667
|
HELP_IDS.REFERENCE_INVALID_OPTIONS_LOCATION
|
|
1632
1668
|
)
|
|
1633
1669
|
)
|
|
1634
|
-
), options ?
|
|
1670
|
+
), options ? isPlainObject(options) ? typeof options.filter == "function" && typeof options.filterParams < "u" ? problems.concat(
|
|
1635
1671
|
error(
|
|
1636
1672
|
"`filterParams` cannot be used if `filter` is a function. Either statically define `filter` as a string, or return `params` from the `filter`-function.",
|
|
1637
1673
|
HELP_IDS.REFERENCE_INVALID_FILTER_PARAMS_COMBINATION
|
|
1638
1674
|
)
|
|
1639
1675
|
) : typeof options.filter == "function" || !options.filter && !options.filterParams ? problems : typeof options.filter != "string" ? problems.concat(
|
|
1640
1676
|
error(`If set, \`filter\` must be a string. Got ${typeof options.filter}`)
|
|
1641
|
-
) : typeof options.filterParams < "u" && !
|
|
1677
|
+
) : typeof options.filterParams < "u" && !isPlainObject(options.filterParams) ? problems.concat(error("If set, `filterParams` must be an object.")) : options.filterParams ? problems.concat(
|
|
1642
1678
|
Object.keys(options.filterParams).filter((key) => key.startsWith("__") || key.startsWith("$")).map((key) => error(`Filter parameter cannot be prefixed with "$" or "__". Got ${key}".`))
|
|
1643
1679
|
) : problems : problems.concat(
|
|
1644
1680
|
error(
|
|
@@ -1658,25 +1694,25 @@ function validateComponent(typeDef) {
|
|
|
1658
1694
|
const warnings = [];
|
|
1659
1695
|
return components.input && !isComponentLike(components.input) && warnings.push(
|
|
1660
1696
|
warning(
|
|
1661
|
-
`The \`components.input\` property is set but does not appear to be a valid React component (expected a function, but saw ${
|
|
1697
|
+
`The \`components.input\` property is set but does not appear to be a valid React component (expected a function, but saw ${inspect(
|
|
1662
1698
|
components.input
|
|
1663
1699
|
)}). If you have imported a custom input component, please verify that you have imported the correct named/default export.`
|
|
1664
1700
|
)
|
|
1665
1701
|
), components.field && !isComponentLike(components.field) && warnings.push(
|
|
1666
1702
|
warning(
|
|
1667
|
-
`The \`components.field\` property is set but does not appear to be a valid React component (expected a function, but saw ${
|
|
1703
|
+
`The \`components.field\` property is set but does not appear to be a valid React component (expected a function, but saw ${inspect(
|
|
1668
1704
|
components.field
|
|
1669
1705
|
)}). If you have imported a custom field component, please verify that you have imported the correct named/default export.`
|
|
1670
1706
|
)
|
|
1671
1707
|
), components.item && !isComponentLike(components.item) && warnings.push(
|
|
1672
1708
|
warning(
|
|
1673
|
-
`The \`components.item\` property is set but does not appear to be a valid React component (expected a function, but saw ${
|
|
1709
|
+
`The \`components.item\` property is set but does not appear to be a valid React component (expected a function, but saw ${inspect(
|
|
1674
1710
|
components.item
|
|
1675
1711
|
)}). If you have imported a custom item component, please verify that you have imported the correct named/default export.`
|
|
1676
1712
|
)
|
|
1677
1713
|
), components.preview && !isComponentLike(components.preview) && warnings.push(
|
|
1678
1714
|
warning(
|
|
1679
|
-
`The \`components.preview\` property is set but does not appear to be a valid React component (expected a function, but saw ${
|
|
1715
|
+
`The \`components.preview\` property is set but does not appear to be a valid React component (expected a function, but saw ${inspect(
|
|
1680
1716
|
components.preview
|
|
1681
1717
|
)}). If you have imported a custom preview component, please verify that you have imported the correct named/default export.`
|
|
1682
1718
|
)
|
|
@@ -1686,7 +1722,7 @@ const VALID_FIELD_RE = /^[A-Za-z]+[0-9A-Za-z_]*$/, CONVENTIONAL_FIELD_RE = /^[A-
|
|
|
1686
1722
|
function validateFieldName(name) {
|
|
1687
1723
|
return typeof name != "string" ? [
|
|
1688
1724
|
error(
|
|
1689
|
-
`Field names must be strings. Saw "${
|
|
1725
|
+
`Field names must be strings. Saw "${inspect(name)}"`,
|
|
1690
1726
|
HELP_IDS.OBJECT_FIELD_NAME_INVALID
|
|
1691
1727
|
)
|
|
1692
1728
|
] : name.startsWith("_") ? [
|
|
@@ -1709,10 +1745,10 @@ function validateFieldName(name) {
|
|
|
1709
1745
|
];
|
|
1710
1746
|
}
|
|
1711
1747
|
function validateField(field, _visitorContext) {
|
|
1712
|
-
if (!
|
|
1748
|
+
if (!isPlainObject(field))
|
|
1713
1749
|
return [
|
|
1714
1750
|
error(
|
|
1715
|
-
`Incorrect type for field definition - should be an object, saw ${
|
|
1751
|
+
`Incorrect type for field definition - should be an object, saw ${inspect(field)}`,
|
|
1716
1752
|
HELP_IDS.OBJECT_FIELD_DEFINITION_INVALID_TYPE
|
|
1717
1753
|
)
|
|
1718
1754
|
];
|
|
@@ -1758,11 +1794,11 @@ function validateFields(fields, options = { allowEmpty: !1 }) {
|
|
|
1758
1794
|
return problems;
|
|
1759
1795
|
}
|
|
1760
1796
|
function validatePreview(preview) {
|
|
1761
|
-
return
|
|
1797
|
+
return isPlainObject(preview) ? typeof preview.prepare < "u" && typeof preview.prepare != "function" ? [
|
|
1762
1798
|
error(
|
|
1763
1799
|
`The "preview.prepare" property must be a function, instead saw "${typeof preview.prepare}"`
|
|
1764
1800
|
)
|
|
1765
|
-
] : preview.select ?
|
|
1801
|
+
] : preview.select ? isPlainObject(preview.select) ? Object.keys(preview.select).reduce((errs, key) => typeof preview.select[key] == "string" ? errs : errs.concat(
|
|
1766
1802
|
error(
|
|
1767
1803
|
`The key "${key}" of "preview.select" must be a string, instead saw "${typeof preview.select[key]}"`
|
|
1768
1804
|
)
|
|
@@ -1795,7 +1831,7 @@ var object = (typeDef, visitorContext) => {
|
|
|
1795
1831
|
};
|
|
1796
1832
|
}, documentVisitor = (typeDefinition, visitorContext) => {
|
|
1797
1833
|
const typeDef = object(typeDefinition, visitorContext), { initialValue, initialValues } = typeDef;
|
|
1798
|
-
return typeof initialValue < "u" && !
|
|
1834
|
+
return typeof initialValue < "u" && !isPlainObject(initialValue) && typeof initialValue != "function" && typeDef._problems.push(
|
|
1799
1835
|
error('The "initialValue" property must be either a plain object or a function')
|
|
1800
1836
|
), typeof initialValues < "u" && typeDef._problems.push(error('Found property "initialValues" - did you mean "initialValue"?')), typeDef;
|
|
1801
1837
|
}, file = (typeDef, visitorContext) => {
|
|
@@ -1830,7 +1866,7 @@ function isValidResourceId(resourceType, resourceId) {
|
|
|
1830
1866
|
return resourceId ? resourceType === "dataset" ? resourceId.split(".").length !== 2 ? 'The resource ID for a dataset reference must be on the form "<projectId>.<datasetName>"' : !0 : resourceType === "media-library" ? !0 : `Cannot validate resource ID for resource type: ${resourceType}` : "The resource ID must be a non-empty string";
|
|
1831
1867
|
}
|
|
1832
1868
|
var globalDocumentReference = (typeDef, visitorContext) => {
|
|
1833
|
-
const isValidTo = Array.isArray(typeDef.to) ||
|
|
1869
|
+
const isValidTo = Array.isArray(typeDef.to) || isPlainObject(typeDef.to), normalizedTo = normalizeToProp$1(typeDef), problems = flatten([
|
|
1834
1870
|
isValidTo ? getDupes(normalizedTo, (t) => `${t.name};${t.type}`).map(
|
|
1835
1871
|
(dupes) => error(
|
|
1836
1872
|
`Found ${dupes.length} members with same type, but not unique names "${dupes[0].type}" in reference. This makes it impossible to tell their values apart and you should consider naming them`,
|
|
@@ -1852,7 +1888,7 @@ var globalDocumentReference = (typeDef, visitorContext) => {
|
|
|
1852
1888
|
`The referenced type at index ${index} must be named. Specify the name of the type you want to create references to.`,
|
|
1853
1889
|
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1854
1890
|
)
|
|
1855
|
-
),
|
|
1891
|
+
), isPlainObject(crossDatasetTypeDef.preview) || problems.push(
|
|
1856
1892
|
error(
|
|
1857
1893
|
`Missing required preview config for the referenced type "${crossDatasetTypeDef.type || "<unknown type>"}"`,
|
|
1858
1894
|
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
@@ -1897,14 +1933,14 @@ function getOptionErrors$1(typeDef) {
|
|
|
1897
1933
|
HELP_IDS.REFERENCE_INVALID_OPTIONS_LOCATION
|
|
1898
1934
|
)
|
|
1899
1935
|
)
|
|
1900
|
-
), options ?
|
|
1936
|
+
), options ? isPlainObject(options) ? typeof options.filter == "function" && typeof options.filterParams < "u" ? problems.concat(
|
|
1901
1937
|
error(
|
|
1902
1938
|
"`filterParams` cannot be used if `filter` is a function. Either statically define `filter` as a string, or return `params` from the `filter`-function.",
|
|
1903
1939
|
HELP_IDS.REFERENCE_INVALID_FILTER_PARAMS_COMBINATION
|
|
1904
1940
|
)
|
|
1905
1941
|
) : typeof options.filter == "function" || !options.filter && !options.filterParams ? problems : typeof options.filter != "string" ? problems.concat(
|
|
1906
1942
|
error(`If set, \`filter\` must be a string. Got ${typeof options.filter}`)
|
|
1907
|
-
) : typeof options.filterParams < "u" && !
|
|
1943
|
+
) : typeof options.filterParams < "u" && !isPlainObject(options.filterParams) ? problems.concat(error("If set, `filterParams` must be an object.")) : options.filterParams ? problems.concat(
|
|
1908
1944
|
Object.keys(options.filterParams).filter((key) => key.startsWith("__") || key.startsWith("$")).map((key) => error(`Filter parameter cannot be prefixed with "$" or "__". Got ${key}".`))
|
|
1909
1945
|
) : problems : problems.concat(
|
|
1910
1946
|
error(
|
|
@@ -1949,138 +1985,842 @@ var image = (typeDef, visitorContext) => {
|
|
|
1949
1985
|
}),
|
|
1950
1986
|
_problems: problems
|
|
1951
1987
|
};
|
|
1952
|
-
};
|
|
1953
|
-
function normalizeToProp(typeDef) {
|
|
1954
|
-
return Array.isArray(typeDef.to) ? typeDef.to : typeDef.to ? [typeDef.to] : typeDef.to;
|
|
1988
|
+
};
|
|
1989
|
+
function normalizeToProp(typeDef) {
|
|
1990
|
+
return Array.isArray(typeDef.to) ? typeDef.to : typeDef.to ? [typeDef.to] : typeDef.to;
|
|
1991
|
+
}
|
|
1992
|
+
var reference = (typeDef, visitorContext) => {
|
|
1993
|
+
const isValidTo = Array.isArray(typeDef.to) || isPlainObject(typeDef.to), normalizedTo = normalizeToProp(typeDef), problems = flatten([
|
|
1994
|
+
isValidTo ? getDupes(normalizedTo, (t) => `${t.name};${t.type}`).map(
|
|
1995
|
+
(dupes) => error(
|
|
1996
|
+
`Found ${dupes.length} members with same type, but not unique names "${dupes[0].type}" in reference. This makes it impossible to tell their values apart and you should consider naming them`,
|
|
1997
|
+
HELP_IDS.REFERENCE_TO_INVALID
|
|
1998
|
+
)
|
|
1999
|
+
) : error(
|
|
2000
|
+
'The reference type is missing or having an invalid value for the required "to" property. It should be an array of accepted types.',
|
|
2001
|
+
HELP_IDS.REFERENCE_TO_INVALID
|
|
2002
|
+
)
|
|
2003
|
+
]);
|
|
2004
|
+
return isValidTo && normalizedTo.length === 0 && problems.push(
|
|
2005
|
+
error(
|
|
2006
|
+
'The reference type should define at least one accepted type. Please check the "to" property.',
|
|
2007
|
+
HELP_IDS.REFERENCE_TO_INVALID
|
|
2008
|
+
)
|
|
2009
|
+
), problems.push(...getOptionErrors(typeDef)), {
|
|
2010
|
+
...typeDef,
|
|
2011
|
+
to: (isValidTo ? normalizedTo : []).map(visitorContext.visit),
|
|
2012
|
+
_problems: problems
|
|
2013
|
+
};
|
|
2014
|
+
};
|
|
2015
|
+
function getOptionErrors(typeDef) {
|
|
2016
|
+
const { options } = typeDef, problems = [];
|
|
2017
|
+
return problems.push(
|
|
2018
|
+
...["filter", "filterParams"].filter((key) => key in typeDef).map(
|
|
2019
|
+
(key) => error(
|
|
2020
|
+
`\`${key}\` is not allowed on a reference type definition - did you mean \`options.${key}\`?`,
|
|
2021
|
+
HELP_IDS.REFERENCE_INVALID_OPTIONS_LOCATION
|
|
2022
|
+
)
|
|
2023
|
+
)
|
|
2024
|
+
), options ? isPlainObject(options) ? typeof options.filter == "function" && typeof options.filterParams < "u" ? problems.concat(
|
|
2025
|
+
error(
|
|
2026
|
+
"`filterParams` cannot be used if `filter` is a function. Either statically define `filter` as a string, or return `params` from the `filter`-function.",
|
|
2027
|
+
HELP_IDS.REFERENCE_INVALID_FILTER_PARAMS_COMBINATION
|
|
2028
|
+
)
|
|
2029
|
+
) : typeof options.filter == "function" || !options.filter && !options.filterParams ? problems : typeof options.filter != "string" ? problems.concat(
|
|
2030
|
+
error(`If set, \`filter\` must be a string. Got ${typeof options.filter}`)
|
|
2031
|
+
) : typeof options.filterParams < "u" && !isPlainObject(options.filterParams) ? problems.concat(error("If set, `filterParams` must be an object.")) : options.filterParams ? problems.concat(
|
|
2032
|
+
Object.keys(options.filterParams).filter((key) => key.startsWith("__") || key.startsWith("$")).map((key) => error(`Filter parameter cannot be prefixed with "$" or "__". Got ${key}".`))
|
|
2033
|
+
) : problems : problems.concat(
|
|
2034
|
+
error(
|
|
2035
|
+
"The reference type expects `options` to be an object",
|
|
2036
|
+
HELP_IDS.REFERENCE_INVALID_OPTIONS
|
|
2037
|
+
)
|
|
2038
|
+
) : problems;
|
|
2039
|
+
}
|
|
2040
|
+
var rootType = (typeDef, visitorContext) => {
|
|
2041
|
+
const hasName = !!typeDef.name;
|
|
2042
|
+
if (!hasName && Object.keys(typeDef).length === 1)
|
|
2043
|
+
return {
|
|
2044
|
+
...typeDef,
|
|
2045
|
+
_problems: [
|
|
2046
|
+
error(
|
|
2047
|
+
"Invalid/undefined type declaration, check declaration or the import/export of the schema type.",
|
|
2048
|
+
HELP_IDS.TYPE_INVALID
|
|
2049
|
+
)
|
|
2050
|
+
]
|
|
2051
|
+
};
|
|
2052
|
+
const problems = [];
|
|
2053
|
+
return looksLikeEsmModule(typeDef) ? problems.push(
|
|
2054
|
+
error(
|
|
2055
|
+
"Type appears to be an ES6 module imported through CommonJS require - use an import statement or access the `.default` property",
|
|
2056
|
+
HELP_IDS.TYPE_IS_ESM_MODULE
|
|
2057
|
+
)
|
|
2058
|
+
) : hasName ? visitorContext.isReserved(typeDef.name) && problems.push(
|
|
2059
|
+
error(
|
|
2060
|
+
`Invalid type name: "${typeDef.name}" is a reserved name.`,
|
|
2061
|
+
HELP_IDS.TYPE_NAME_RESERVED
|
|
2062
|
+
)
|
|
2063
|
+
) : problems.push(error("Missing type name", HELP_IDS.TYPE_MISSING_NAME)), visitorContext.isDuplicate(typeDef.name) && problems.push(
|
|
2064
|
+
error(
|
|
2065
|
+
`Invalid type name: A type with name "${typeDef.name}" is already defined in the schema.`
|
|
2066
|
+
)
|
|
2067
|
+
), problems.push(...validateComponent(typeDef)), "title" in typeDef && typeof typeDef.title != "string" && problems.push(warning("Type title is not a string.", HELP_IDS.TYPE_TITLE_INVALID)), {
|
|
2068
|
+
...typeDef,
|
|
2069
|
+
_problems: problems
|
|
2070
|
+
};
|
|
2071
|
+
};
|
|
2072
|
+
function looksLikeEsmModule(typeDef) {
|
|
2073
|
+
return !typeDef.name && typeDef.default && (typeDef.default.name || typeDef.default.title);
|
|
2074
|
+
}
|
|
2075
|
+
var slug = (typeDef, visitorContext) => {
|
|
2076
|
+
const problems = [];
|
|
2077
|
+
return typeDef.options && typeDef.options.slugifyFn && (problems.push(
|
|
2078
|
+
warning(
|
|
2079
|
+
'Heads up! The "slugifyFn" option has been renamed to "slugify".',
|
|
2080
|
+
HELP_IDS.SLUG_SLUGIFY_FN_RENAMED
|
|
2081
|
+
)
|
|
2082
|
+
), typeDef.options.slugify = typeDef.options.slugifyFn), {
|
|
2083
|
+
...typeDef,
|
|
2084
|
+
_problems: problems
|
|
2085
|
+
};
|
|
2086
|
+
};
|
|
2087
|
+
const typeVisitors = {
|
|
2088
|
+
array,
|
|
2089
|
+
object,
|
|
2090
|
+
slug,
|
|
2091
|
+
file,
|
|
2092
|
+
image,
|
|
2093
|
+
block: validateBlockType,
|
|
2094
|
+
document: documentVisitor,
|
|
2095
|
+
reference,
|
|
2096
|
+
crossDatasetReference,
|
|
2097
|
+
globalDocumentReference
|
|
2098
|
+
}, getNoopVisitor = (visitorContext) => (schemaDef) => ({
|
|
2099
|
+
name: `<unnamed_type_@_index_${visitorContext.index}>`,
|
|
2100
|
+
...schemaDef,
|
|
2101
|
+
_problems: []
|
|
2102
|
+
});
|
|
2103
|
+
function combine(...visitors) {
|
|
2104
|
+
return (schemaType, visitorContext) => visitors.reduce(
|
|
2105
|
+
(result, visitor) => {
|
|
2106
|
+
const res = visitor(result, visitorContext);
|
|
2107
|
+
return {
|
|
2108
|
+
...res,
|
|
2109
|
+
_problems: result._problems.concat(res._problems)
|
|
2110
|
+
};
|
|
2111
|
+
},
|
|
2112
|
+
{ _problems: [], ...schemaType }
|
|
2113
|
+
);
|
|
2114
|
+
}
|
|
2115
|
+
function validateSchema(schemaTypes, {
|
|
2116
|
+
transformTypeVisitors = (visitors) => visitors,
|
|
2117
|
+
transformCommonVisitors = (visitors) => visitors
|
|
2118
|
+
} = {}) {
|
|
2119
|
+
return traverseSanitySchema(schemaTypes, (schemaDef, visitorContext) => {
|
|
2120
|
+
const typeVisitor = schemaDef && schemaDef.type && transformTypeVisitors(typeVisitors)[schemaDef.type] || getNoopVisitor(visitorContext), commonVisitors = transformCommonVisitors([common]);
|
|
2121
|
+
return visitorContext.isRoot ? combine(rootType, ...commonVisitors, typeVisitor)(schemaDef, visitorContext) : combine(...commonVisitors, typeVisitor)(schemaDef, visitorContext);
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
class ValidationError extends Error {
|
|
2125
|
+
problems;
|
|
2126
|
+
constructor(problems) {
|
|
2127
|
+
super("ValidationError"), this.problems = problems, this.name = "ValidationError";
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
const builtinSchema = Schema.compile({
|
|
2131
|
+
name: "studio",
|
|
2132
|
+
types: builtinTypes
|
|
2133
|
+
});
|
|
2134
|
+
function createSchemaFromManifestTypes(schemaDef) {
|
|
2135
|
+
const validated = validateSchema(schemaDef.types).getTypes(), problems = groupProblems(validated).filter(
|
|
2136
|
+
(group) => group.problems.some((problem) => problem.severity === "error")
|
|
2137
|
+
);
|
|
2138
|
+
if (problems.length > 0)
|
|
2139
|
+
throw new ValidationError(problems);
|
|
2140
|
+
return Schema.compile({
|
|
2141
|
+
name: schemaDef.name,
|
|
2142
|
+
types: schemaDef.types.map(coerceType).filter(Boolean),
|
|
2143
|
+
parent: builtinSchema
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2146
|
+
function coerceType(obj) {
|
|
2147
|
+
if (!isObject(obj)) return;
|
|
2148
|
+
const typ = cloneDeep(obj);
|
|
2149
|
+
return traverse(typ), typ;
|
|
2150
|
+
}
|
|
2151
|
+
function traverse(obj) {
|
|
2152
|
+
if (isObject(obj)) {
|
|
2153
|
+
if (Array.isArray(obj)) {
|
|
2154
|
+
obj.forEach(traverse);
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2157
|
+
for (const v of Object.values(obj))
|
|
2158
|
+
traverse(v);
|
|
2159
|
+
coerceValidation(obj);
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
function coerceValidation(val) {
|
|
2163
|
+
if (!isObject(val) || !("validation" in val)) return;
|
|
2164
|
+
const manifestValidation = Array.isArray(val.validation) ? val.validation : [val.validation];
|
|
2165
|
+
val.validation = manifestValidation.map((group) => {
|
|
2166
|
+
if (isObject(group))
|
|
2167
|
+
return (baseRule) => {
|
|
2168
|
+
let rule = baseRule;
|
|
2169
|
+
const level = "level" in group ? group.level : void 0, rules = "rules" in group ? group.rules : void 0, message = "message" in group ? group.message : void 0;
|
|
2170
|
+
if (!(!rules || !Array.isArray(rules))) {
|
|
2171
|
+
isValidLevel(level) && (message === void 0 || typeof message == "string") && (rule = rule[level](message));
|
|
2172
|
+
for (const ruleSpec of rules)
|
|
2173
|
+
rule = applyRuleSpec(rule, ruleSpec);
|
|
2174
|
+
return rule;
|
|
2175
|
+
}
|
|
2176
|
+
};
|
|
2177
|
+
}).filter(Boolean);
|
|
2178
|
+
}
|
|
2179
|
+
function coerceConstraintRule(val) {
|
|
2180
|
+
if (isObject(val))
|
|
2181
|
+
return Array.isArray(val) ? val.map(coerceConstraintRule).filter(Boolean) : (baseRule) => {
|
|
2182
|
+
let rule = baseRule;
|
|
2183
|
+
const rules = "_rules" in val ? val._rules : void 0, level = "_level" in val ? val._level : void 0, message = "_message" in val ? val._message : void 0;
|
|
2184
|
+
if (!(!rules || !Array.isArray(rules))) {
|
|
2185
|
+
typeof level == "string" && (rule = rule[level](message));
|
|
2186
|
+
for (const ruleSpec of rules)
|
|
2187
|
+
rule = applyRuleSpec(rule, ruleSpec);
|
|
2188
|
+
return rule;
|
|
2189
|
+
}
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
function applyRuleSpec(rule, ruleSpec) {
|
|
2193
|
+
if (!ruleSpec || typeof ruleSpec != "object")
|
|
2194
|
+
return rule;
|
|
2195
|
+
const flag = "flag" in ruleSpec ? ruleSpec.flag : void 0, constraint = "constraint" in ruleSpec ? ruleSpec.constraint : void 0;
|
|
2196
|
+
switch (flag) {
|
|
2197
|
+
case "presence":
|
|
2198
|
+
if (constraint === "required")
|
|
2199
|
+
return rule.required();
|
|
2200
|
+
if (constraint === "optional")
|
|
2201
|
+
return rule.optional();
|
|
2202
|
+
break;
|
|
2203
|
+
case "type":
|
|
2204
|
+
if (typeof constraint == "string")
|
|
2205
|
+
return rule.type(constraint);
|
|
2206
|
+
break;
|
|
2207
|
+
case "min":
|
|
2208
|
+
if (typeof constraint == "number" || typeof constraint == "string")
|
|
2209
|
+
return rule.min(constraint);
|
|
2210
|
+
break;
|
|
2211
|
+
case "max":
|
|
2212
|
+
if (typeof constraint == "number" || typeof constraint == "string")
|
|
2213
|
+
return rule.max(constraint);
|
|
2214
|
+
break;
|
|
2215
|
+
case "length":
|
|
2216
|
+
if (typeof constraint == "number")
|
|
2217
|
+
return rule.length(constraint);
|
|
2218
|
+
break;
|
|
2219
|
+
case "integer":
|
|
2220
|
+
return rule.integer();
|
|
2221
|
+
case "email":
|
|
2222
|
+
return rule.email();
|
|
2223
|
+
case "unique":
|
|
2224
|
+
return rule.unique();
|
|
2225
|
+
case "reference":
|
|
2226
|
+
return rule.reference();
|
|
2227
|
+
case "precision":
|
|
2228
|
+
if (typeof constraint == "number")
|
|
2229
|
+
return rule.precision(constraint);
|
|
2230
|
+
break;
|
|
2231
|
+
case "positive":
|
|
2232
|
+
return rule.positive();
|
|
2233
|
+
case "negative":
|
|
2234
|
+
return rule.negative();
|
|
2235
|
+
case "greaterThan":
|
|
2236
|
+
if (typeof constraint == "number")
|
|
2237
|
+
return rule.greaterThan(constraint);
|
|
2238
|
+
break;
|
|
2239
|
+
case "lessThan":
|
|
2240
|
+
if (typeof constraint == "number")
|
|
2241
|
+
return rule.lessThan(constraint);
|
|
2242
|
+
break;
|
|
2243
|
+
case "stringCasing":
|
|
2244
|
+
if (constraint === "uppercase")
|
|
2245
|
+
return rule.uppercase();
|
|
2246
|
+
if (constraint === "lowercase")
|
|
2247
|
+
return rule.lowercase();
|
|
2248
|
+
break;
|
|
2249
|
+
case "valid":
|
|
2250
|
+
if (Array.isArray(constraint))
|
|
2251
|
+
return rule.valid(constraint);
|
|
2252
|
+
break;
|
|
2253
|
+
case "regex":
|
|
2254
|
+
if (isObject(constraint) && "pattern" in constraint && (typeof constraint.pattern == "string" || constraint.pattern instanceof RegExp)) {
|
|
2255
|
+
const options = {};
|
|
2256
|
+
"name" in constraint && typeof constraint.name == "string" && (options.name = constraint.name), "invert" in constraint && (options.invert = constraint.invert);
|
|
2257
|
+
const pattern = typeof constraint.pattern == "string" ? stringToRegExp(constraint.pattern) : constraint.pattern;
|
|
2258
|
+
return rule.regex(pattern, options);
|
|
2259
|
+
}
|
|
2260
|
+
break;
|
|
2261
|
+
case "uri":
|
|
2262
|
+
if (isObject(constraint) && "options" in constraint)
|
|
2263
|
+
return rule.uri(constraint.options);
|
|
2264
|
+
break;
|
|
2265
|
+
case "assetRequired":
|
|
2266
|
+
return rule.assetRequired();
|
|
2267
|
+
case "all":
|
|
2268
|
+
return rule.all(coerceConstraintRule(constraint));
|
|
2269
|
+
case "either":
|
|
2270
|
+
return rule.either(coerceConstraintRule(constraint));
|
|
2271
|
+
case "custom":
|
|
2272
|
+
if (constraint === void 0) return rule.custom(() => !0);
|
|
2273
|
+
if (typeof constraint == "function") return rule.custom(constraint);
|
|
2274
|
+
break;
|
|
2275
|
+
case "media":
|
|
2276
|
+
if (constraint === void 0) return rule.media(() => !0);
|
|
2277
|
+
if (typeof constraint == "function") return rule.media(constraint);
|
|
2278
|
+
break;
|
|
2279
|
+
}
|
|
2280
|
+
return rule;
|
|
2281
|
+
}
|
|
2282
|
+
const isValidLevel = (level) => !!level && typeof level == "string" && ["error", "warning", "info"].includes(level);
|
|
2283
|
+
function stringToRegExp(str) {
|
|
2284
|
+
const match = str.match(/^\/(.*)\/([gimuy]*)$/);
|
|
2285
|
+
return match ? new RegExp(match[1], match[2]) : new RegExp(str);
|
|
2286
|
+
}
|
|
2287
|
+
const documentDefaultFields = (typeName) => ({
|
|
2288
|
+
_id: {
|
|
2289
|
+
type: "objectAttribute",
|
|
2290
|
+
value: { type: "string" }
|
|
2291
|
+
},
|
|
2292
|
+
_type: {
|
|
2293
|
+
type: "objectAttribute",
|
|
2294
|
+
value: { type: "string", value: typeName }
|
|
2295
|
+
},
|
|
2296
|
+
_createdAt: {
|
|
2297
|
+
type: "objectAttribute",
|
|
2298
|
+
value: { type: "string" }
|
|
2299
|
+
},
|
|
2300
|
+
_updatedAt: {
|
|
2301
|
+
type: "objectAttribute",
|
|
2302
|
+
value: { type: "string" }
|
|
2303
|
+
},
|
|
2304
|
+
_rev: {
|
|
2305
|
+
type: "objectAttribute",
|
|
2306
|
+
value: { type: "string" }
|
|
2307
|
+
}
|
|
2308
|
+
}), typesMap = /* @__PURE__ */ new Map([
|
|
2309
|
+
["text", { type: "string" }],
|
|
2310
|
+
["url", { type: "string" }],
|
|
2311
|
+
["datetime", { type: "string" }],
|
|
2312
|
+
["date", { type: "string" }],
|
|
2313
|
+
["boolean", { type: "boolean" }],
|
|
2314
|
+
["email", { type: "string" }]
|
|
2315
|
+
]);
|
|
2316
|
+
function extractSchema(schemaDef, extractOptions = {}) {
|
|
2317
|
+
const inlineFields = /* @__PURE__ */ new Set(), documentTypes = /* @__PURE__ */ new Map(), schema = [], generatedTypes = /* @__PURE__ */ new Map(), { sortedSchemaTypeNames, repeated } = sortByDependencies(schemaDef);
|
|
2318
|
+
repeated.forEach((key, objectField) => {
|
|
2319
|
+
const base = convertSchemaType(objectField.type);
|
|
2320
|
+
if (base !== null) {
|
|
2321
|
+
if (base.type === "inline") {
|
|
2322
|
+
repeated.delete(objectField);
|
|
2323
|
+
return;
|
|
2324
|
+
}
|
|
2325
|
+
if (base.type === "unknown") {
|
|
2326
|
+
repeated.delete(objectField);
|
|
2327
|
+
return;
|
|
2328
|
+
}
|
|
2329
|
+
schema.push({
|
|
2330
|
+
type: "type",
|
|
2331
|
+
name: getGeneratedTypeName(key),
|
|
2332
|
+
value: base
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
}), sortedSchemaTypeNames.forEach((typeName) => {
|
|
2336
|
+
const schemaType = schemaDef.get(typeName);
|
|
2337
|
+
if (schemaType === void 0)
|
|
2338
|
+
return;
|
|
2339
|
+
const base = convertBaseType(schemaType);
|
|
2340
|
+
base !== null && (base.type === "type" && inlineFields.add(schemaType), base.type === "document" && documentTypes.set(typeName, base), schema.push(base));
|
|
2341
|
+
});
|
|
2342
|
+
function getGeneratedTypeName(typeName, suffix = "") {
|
|
2343
|
+
const name = generatedTypes.get(typeName);
|
|
2344
|
+
if (name) return name;
|
|
2345
|
+
for (let i = 0; i < 5; i++) {
|
|
2346
|
+
const uniqueName = `${typeName}${suffix}${i || ""}`;
|
|
2347
|
+
if (!sortedSchemaTypeNames.includes(uniqueName))
|
|
2348
|
+
return generatedTypes.set(typeName, uniqueName), uniqueName;
|
|
2349
|
+
}
|
|
2350
|
+
throw new Error(`Unable to generate unique type name for ${typeName}.`);
|
|
2351
|
+
}
|
|
2352
|
+
function convertBaseType(schemaType) {
|
|
2353
|
+
let typeName;
|
|
2354
|
+
if (schemaType.type ? typeName = schemaType.type.name : "jsonType" in schemaType && (typeName = schemaType.jsonType), typeName === "document" && isObjectType(schemaType)) {
|
|
2355
|
+
const defaultAttributes = documentDefaultFields(schemaType.name), object2 = createObject(schemaType);
|
|
2356
|
+
return object2.type === "unknown" ? null : {
|
|
2357
|
+
name: schemaType.name,
|
|
2358
|
+
type: "document",
|
|
2359
|
+
attributes: {
|
|
2360
|
+
...defaultAttributes,
|
|
2361
|
+
...object2.attributes
|
|
2362
|
+
}
|
|
2363
|
+
};
|
|
2364
|
+
}
|
|
2365
|
+
const value = convertSchemaType(schemaType);
|
|
2366
|
+
return value.type === "unknown" ? null : value.type === "object" ? (value.attributes = {
|
|
2367
|
+
_type: {
|
|
2368
|
+
type: "objectAttribute",
|
|
2369
|
+
value: {
|
|
2370
|
+
type: "string",
|
|
2371
|
+
value: schemaType.name
|
|
2372
|
+
}
|
|
2373
|
+
},
|
|
2374
|
+
...value.attributes
|
|
2375
|
+
}, {
|
|
2376
|
+
name: schemaType.name,
|
|
2377
|
+
type: "type",
|
|
2378
|
+
value
|
|
2379
|
+
}) : {
|
|
2380
|
+
name: schemaType.name,
|
|
2381
|
+
type: "type",
|
|
2382
|
+
value
|
|
2383
|
+
};
|
|
2384
|
+
}
|
|
2385
|
+
function convertSchemaType(schemaType) {
|
|
2386
|
+
if (inlineFields.has(schemaType.type))
|
|
2387
|
+
return { type: "inline", name: schemaType.type.name };
|
|
2388
|
+
if (schemaType.type?.name && sortedSchemaTypeNames.indexOf(schemaType.type?.name) > -1)
|
|
2389
|
+
return { type: "inline", name: schemaType.type?.name };
|
|
2390
|
+
if (isStringType(schemaType))
|
|
2391
|
+
return createStringTypeNodeDefintion(schemaType);
|
|
2392
|
+
if (isNumberType(schemaType))
|
|
2393
|
+
return createNumberTypeNodeDefintion(schemaType);
|
|
2394
|
+
if (schemaType.type && typesMap.has(schemaType.type.name))
|
|
2395
|
+
return typesMap.get(schemaType.type.name);
|
|
2396
|
+
if (isCrossDatasetReferenceType(schemaType))
|
|
2397
|
+
return { type: "unknown" };
|
|
2398
|
+
if (isGlobalDocumentReferenceType(schemaType))
|
|
2399
|
+
return { type: "unknown" };
|
|
2400
|
+
if (isReferenceType(schemaType))
|
|
2401
|
+
return createReferenceTypeNodeDefintion(schemaType);
|
|
2402
|
+
if (isArrayType(schemaType))
|
|
2403
|
+
return createArray(schemaType);
|
|
2404
|
+
if (isObjectType(schemaType))
|
|
2405
|
+
return createObject(schemaType);
|
|
2406
|
+
if (lastType(schemaType)?.name === "document") {
|
|
2407
|
+
const doc = documentTypes.get(schemaType.name);
|
|
2408
|
+
return doc === void 0 ? { type: "unknown" } : { type: "object", attributes: doc?.attributes };
|
|
2409
|
+
}
|
|
2410
|
+
throw new Error(`Type "${schemaType.name}" not found`);
|
|
2411
|
+
}
|
|
2412
|
+
function createObject(schemaType) {
|
|
2413
|
+
const attributes = {}, fields = gatherFields(schemaType);
|
|
2414
|
+
for (const field of fields) {
|
|
2415
|
+
const fieldIsRequired = isFieldRequired(field?.type?.validation);
|
|
2416
|
+
let value;
|
|
2417
|
+
const hoisted = repeated.get(field), isTopLevelSchemaType = sortedSchemaTypeNames.includes(field.type.name);
|
|
2418
|
+
if (hoisted && !isTopLevelSchemaType)
|
|
2419
|
+
value = {
|
|
2420
|
+
type: "inline",
|
|
2421
|
+
name: getGeneratedTypeName(hoisted)
|
|
2422
|
+
};
|
|
2423
|
+
else {
|
|
2424
|
+
if (value = convertSchemaType(field.type), value === null)
|
|
2425
|
+
continue;
|
|
2426
|
+
hasAssetRequired(field?.type?.validation) && value.type === "object" && (value.attributes.asset.optional = !1);
|
|
2427
|
+
}
|
|
2428
|
+
const optional = extractOptions.enforceRequiredFields ? fieldIsRequired === !1 : !0;
|
|
2429
|
+
attributes[field.name] = {
|
|
2430
|
+
type: "objectAttribute",
|
|
2431
|
+
value,
|
|
2432
|
+
optional
|
|
2433
|
+
};
|
|
2434
|
+
}
|
|
2435
|
+
return extractOptions.enforceRequiredFields && hasAssetRequired(schemaType.validation) && attributes.asset && (attributes.asset.optional = !1), Object.keys(attributes).length === 0 ? { type: "unknown" } : (schemaType.type?.name !== "document" && schemaType.name !== "object" && (attributes._type = {
|
|
2436
|
+
type: "objectAttribute",
|
|
2437
|
+
value: {
|
|
2438
|
+
type: "string",
|
|
2439
|
+
value: schemaType.name
|
|
2440
|
+
}
|
|
2441
|
+
}), {
|
|
2442
|
+
type: "object",
|
|
2443
|
+
attributes
|
|
2444
|
+
});
|
|
2445
|
+
}
|
|
2446
|
+
function createArray(arraySchemaType) {
|
|
2447
|
+
const of = [];
|
|
2448
|
+
for (const item of arraySchemaType.of) {
|
|
2449
|
+
const field = convertSchemaType(item);
|
|
2450
|
+
field.type === "inline" ? of.push({
|
|
2451
|
+
type: "object",
|
|
2452
|
+
attributes: {
|
|
2453
|
+
_key: createKeyField()
|
|
2454
|
+
},
|
|
2455
|
+
rest: field
|
|
2456
|
+
}) : (field.type === "object" && (field.rest = {
|
|
2457
|
+
type: "object",
|
|
2458
|
+
attributes: {
|
|
2459
|
+
_key: createKeyField()
|
|
2460
|
+
}
|
|
2461
|
+
}), of.push(field));
|
|
2462
|
+
}
|
|
2463
|
+
return of.length === 0 ? { type: "null" } : {
|
|
2464
|
+
type: "array",
|
|
2465
|
+
of: of.length > 1 ? {
|
|
2466
|
+
type: "union",
|
|
2467
|
+
of
|
|
2468
|
+
} : of[0]
|
|
2469
|
+
};
|
|
2470
|
+
}
|
|
2471
|
+
function createReferenceTypeNodeDefintion(reference2) {
|
|
2472
|
+
const references = gatherReferenceNames(reference2);
|
|
2473
|
+
for (const name of references)
|
|
2474
|
+
generatedTypes.has(name) || schema.push({
|
|
2475
|
+
type: "type",
|
|
2476
|
+
name: getGeneratedTypeName(name, ".reference"),
|
|
2477
|
+
value: createReferenceTypeNode(name)
|
|
2478
|
+
});
|
|
2479
|
+
return references.length === 1 ? { type: "inline", name: getGeneratedTypeName(references[0], ".reference") } : {
|
|
2480
|
+
type: "union",
|
|
2481
|
+
of: references.map((name) => ({
|
|
2482
|
+
type: "inline",
|
|
2483
|
+
name: getGeneratedTypeName(name, ".reference")
|
|
2484
|
+
}))
|
|
2485
|
+
};
|
|
2486
|
+
}
|
|
2487
|
+
return schema;
|
|
2488
|
+
}
|
|
2489
|
+
function createKeyField() {
|
|
2490
|
+
return {
|
|
2491
|
+
type: "objectAttribute",
|
|
2492
|
+
value: {
|
|
2493
|
+
type: "string"
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2497
|
+
function isFieldRequired(validation) {
|
|
2498
|
+
if (!validation)
|
|
2499
|
+
return !1;
|
|
2500
|
+
const rules = Array.isArray(validation) ? validation : [validation];
|
|
2501
|
+
for (const rule of rules) {
|
|
2502
|
+
let required = !1;
|
|
2503
|
+
const proxy = new Proxy(
|
|
2504
|
+
{},
|
|
2505
|
+
{
|
|
2506
|
+
get: (target, methodName) => () => (methodName === "required" && (required = !0), proxy)
|
|
2507
|
+
}
|
|
2508
|
+
);
|
|
2509
|
+
if (typeof rule == "function" && (rule(proxy), required) || typeof rule == "object" && rule !== null && "_required" in rule && rule._required === "required")
|
|
2510
|
+
return !0;
|
|
2511
|
+
}
|
|
2512
|
+
return !1;
|
|
2513
|
+
}
|
|
2514
|
+
function hasAssetRequired(validation) {
|
|
2515
|
+
if (!validation)
|
|
2516
|
+
return !1;
|
|
2517
|
+
const rules = Array.isArray(validation) ? validation : [validation];
|
|
2518
|
+
for (const rule of rules) {
|
|
2519
|
+
let assetRequired = !1;
|
|
2520
|
+
const proxy = new Proxy(
|
|
2521
|
+
{},
|
|
2522
|
+
{
|
|
2523
|
+
get: (target, methodName) => () => (methodName === "assetRequired" && (assetRequired = !0), proxy)
|
|
2524
|
+
}
|
|
2525
|
+
);
|
|
2526
|
+
if (typeof rule == "function" && (rule(proxy), assetRequired) || typeof rule == "object" && rule !== null && "_rules" in rule && Array.isArray(rule._rules) && rule._rules.some((r) => r.flag === "assetRequired"))
|
|
2527
|
+
return !0;
|
|
2528
|
+
}
|
|
2529
|
+
return !1;
|
|
2530
|
+
}
|
|
2531
|
+
function isObjectType(typeDef) {
|
|
2532
|
+
return isType(typeDef, "object") || typeDef.jsonType === "object" || "fields" in typeDef;
|
|
2533
|
+
}
|
|
2534
|
+
function isArrayType(typeDef) {
|
|
2535
|
+
return isType(typeDef, "array");
|
|
2536
|
+
}
|
|
2537
|
+
function isReferenceType(typeDef) {
|
|
2538
|
+
return isType(typeDef, "reference");
|
|
2539
|
+
}
|
|
2540
|
+
function isCrossDatasetReferenceType(typeDef) {
|
|
2541
|
+
return isType(typeDef, "crossDatasetReference");
|
|
2542
|
+
}
|
|
2543
|
+
function isGlobalDocumentReferenceType(typeDef) {
|
|
2544
|
+
return isType(typeDef, "globalDocumentReference");
|
|
2545
|
+
}
|
|
2546
|
+
function isStringType(typeDef) {
|
|
2547
|
+
return isType(typeDef, "string");
|
|
2548
|
+
}
|
|
2549
|
+
function isNumberType(typeDef) {
|
|
2550
|
+
return isType(typeDef, "number");
|
|
2551
|
+
}
|
|
2552
|
+
function createStringTypeNodeDefintion(stringSchemaType) {
|
|
2553
|
+
const listOptions = stringSchemaType.options?.list;
|
|
2554
|
+
return listOptions && Array.isArray(listOptions) ? {
|
|
2555
|
+
type: "union",
|
|
2556
|
+
of: listOptions.map((v) => ({
|
|
2557
|
+
type: "string",
|
|
2558
|
+
value: typeof v == "string" ? v : v.value
|
|
2559
|
+
}))
|
|
2560
|
+
} : {
|
|
2561
|
+
type: "string"
|
|
2562
|
+
};
|
|
1955
2563
|
}
|
|
1956
|
-
|
|
1957
|
-
const
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
)
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
)
|
|
1967
|
-
]);
|
|
1968
|
-
return isValidTo && normalizedTo.length === 0 && problems.push(
|
|
1969
|
-
error(
|
|
1970
|
-
'The reference type should define at least one accepted type. Please check the "to" property.',
|
|
1971
|
-
HELP_IDS.REFERENCE_TO_INVALID
|
|
1972
|
-
)
|
|
1973
|
-
), problems.push(...getOptionErrors(typeDef)), {
|
|
1974
|
-
...typeDef,
|
|
1975
|
-
to: (isValidTo ? normalizedTo : []).map(visitorContext.visit),
|
|
1976
|
-
_problems: problems
|
|
2564
|
+
function createNumberTypeNodeDefintion(numberSchemaType) {
|
|
2565
|
+
const listOptions = numberSchemaType.options?.list;
|
|
2566
|
+
return listOptions && Array.isArray(listOptions) ? {
|
|
2567
|
+
type: "union",
|
|
2568
|
+
of: listOptions.map((v) => ({
|
|
2569
|
+
type: "number",
|
|
2570
|
+
value: typeof v == "number" ? v : v.value
|
|
2571
|
+
}))
|
|
2572
|
+
} : {
|
|
2573
|
+
type: "number"
|
|
1977
2574
|
};
|
|
1978
|
-
};
|
|
1979
|
-
function getOptionErrors(typeDef) {
|
|
1980
|
-
const { options } = typeDef, problems = [];
|
|
1981
|
-
return problems.push(
|
|
1982
|
-
...["filter", "filterParams"].filter((key) => key in typeDef).map(
|
|
1983
|
-
(key) => error(
|
|
1984
|
-
`\`${key}\` is not allowed on a reference type definition - did you mean \`options.${key}\`?`,
|
|
1985
|
-
HELP_IDS.REFERENCE_INVALID_OPTIONS_LOCATION
|
|
1986
|
-
)
|
|
1987
|
-
)
|
|
1988
|
-
), options ? isPlainObject__default.default(options) ? typeof options.filter == "function" && typeof options.filterParams < "u" ? problems.concat(
|
|
1989
|
-
error(
|
|
1990
|
-
"`filterParams` cannot be used if `filter` is a function. Either statically define `filter` as a string, or return `params` from the `filter`-function.",
|
|
1991
|
-
HELP_IDS.REFERENCE_INVALID_FILTER_PARAMS_COMBINATION
|
|
1992
|
-
)
|
|
1993
|
-
) : typeof options.filter == "function" || !options.filter && !options.filterParams ? problems : typeof options.filter != "string" ? problems.concat(
|
|
1994
|
-
error(`If set, \`filter\` must be a string. Got ${typeof options.filter}`)
|
|
1995
|
-
) : typeof options.filterParams < "u" && !isPlainObject__default.default(options.filterParams) ? problems.concat(error("If set, `filterParams` must be an object.")) : options.filterParams ? problems.concat(
|
|
1996
|
-
Object.keys(options.filterParams).filter((key) => key.startsWith("__") || key.startsWith("$")).map((key) => error(`Filter parameter cannot be prefixed with "$" or "__". Got ${key}".`))
|
|
1997
|
-
) : problems : problems.concat(
|
|
1998
|
-
error(
|
|
1999
|
-
"The reference type expects `options` to be an object",
|
|
2000
|
-
HELP_IDS.REFERENCE_INVALID_OPTIONS
|
|
2001
|
-
)
|
|
2002
|
-
) : problems;
|
|
2003
2575
|
}
|
|
2004
|
-
|
|
2005
|
-
const
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2576
|
+
function gatherReferenceNames(type) {
|
|
2577
|
+
const allReferences = gatherReferenceTypes(type);
|
|
2578
|
+
return [...new Set(allReferences.map((ref) => ref.name))];
|
|
2579
|
+
}
|
|
2580
|
+
function gatherReferenceTypes(type) {
|
|
2581
|
+
const refTo = "to" in type ? type.to : [];
|
|
2582
|
+
return "type" in type && isReferenceType(type.type) ? [...gatherReferenceTypes(type.type), ...refTo] : refTo;
|
|
2583
|
+
}
|
|
2584
|
+
function gatherFields(type) {
|
|
2585
|
+
return "fields" in type ? type.type ? gatherFields(type.type).concat(type.fields) : type.fields : [];
|
|
2586
|
+
}
|
|
2587
|
+
function isType(typeDef, typeName) {
|
|
2588
|
+
let type = typeDef;
|
|
2589
|
+
for (; type; ) {
|
|
2590
|
+
if (type.name === typeName || type.type && type.type.name === typeName)
|
|
2591
|
+
return !0;
|
|
2592
|
+
type = type.type;
|
|
2593
|
+
}
|
|
2594
|
+
return !1;
|
|
2595
|
+
}
|
|
2596
|
+
function lastType(typeDef) {
|
|
2597
|
+
let type = typeDef;
|
|
2598
|
+
for (; type; ) {
|
|
2599
|
+
if (!type.type)
|
|
2600
|
+
return type;
|
|
2601
|
+
type = type.type;
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
function sortByDependencies(compiledSchema) {
|
|
2605
|
+
const seen = /* @__PURE__ */ new Set(), objectMap = /* @__PURE__ */ new Set(), repeated = /* @__PURE__ */ new Map(), repeatedNames = /* @__PURE__ */ new Set();
|
|
2606
|
+
function pickRepeatedName(path) {
|
|
2607
|
+
for (let idx = path.length - 1; idx >= 0; idx--) {
|
|
2608
|
+
const name = path.slice(idx).join(".");
|
|
2609
|
+
if (!repeatedNames.has(name))
|
|
2610
|
+
return repeatedNames.add(name), name;
|
|
2611
|
+
}
|
|
2612
|
+
throw new Error(`Unable to pick repeated name: ${path.join(".")}`);
|
|
2613
|
+
}
|
|
2614
|
+
function walkDependencies(schemaType, dependencies, path, hoistRepetitions = !0) {
|
|
2615
|
+
if (!seen.has(schemaType)) {
|
|
2616
|
+
if (seen.add(schemaType), "fields" in schemaType)
|
|
2617
|
+
for (const field of gatherFields(schemaType)) {
|
|
2618
|
+
const last = lastType(field.type);
|
|
2619
|
+
if (last.name === "document") {
|
|
2620
|
+
dependencies.add(last);
|
|
2621
|
+
continue;
|
|
2622
|
+
}
|
|
2623
|
+
let schemaTypeName;
|
|
2624
|
+
if (schemaType.type.type ? schemaTypeName = field.type.type.name : "jsonType" in schemaType.type && (schemaTypeName = field.type.jsonType), schemaTypeName === "object" || schemaTypeName === "block") {
|
|
2625
|
+
if (isReferenceType(field.type))
|
|
2626
|
+
field.type.to.forEach((ref) => dependencies.add(ref.type));
|
|
2627
|
+
else if (dependencies.add(field.type), hoistRepetitions && !validSchemaNames.has(field.type.name)) {
|
|
2628
|
+
const fieldPath = path.concat([field.name]);
|
|
2629
|
+
!repeated.has(field) && objectMap.has(field) && repeated.set(field, pickRepeatedName(fieldPath)), objectMap.add(field);
|
|
2630
|
+
}
|
|
2631
|
+
} else field.type && dependencies.add(field.type);
|
|
2632
|
+
walkDependencies(field.type, dependencies, path.concat([field.name]));
|
|
2633
|
+
}
|
|
2634
|
+
else if ("of" in schemaType)
|
|
2635
|
+
for (const item of schemaType.of)
|
|
2636
|
+
walkDependencies(item, dependencies, path.concat(item.name), !isReferenceType(schemaType));
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
const dependencyMap = /* @__PURE__ */ new Map(), schemaTypeNames = compiledSchema.getTypeNames(), validSchemaNames = /* @__PURE__ */ new Set();
|
|
2640
|
+
schemaTypeNames.forEach((typeName) => {
|
|
2641
|
+
const schemaType = compiledSchema.get(typeName);
|
|
2642
|
+
if (schemaType === void 0 || schemaType.type === null)
|
|
2643
|
+
return;
|
|
2644
|
+
validSchemaNames.add(typeName);
|
|
2645
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
2646
|
+
walkDependencies(schemaType, dependencies, [typeName]), dependencyMap.set(schemaType, dependencies), seen.clear();
|
|
2647
|
+
});
|
|
2648
|
+
const typeNames = [], currentlyVisiting = /* @__PURE__ */ new Set(), visited = /* @__PURE__ */ new Set();
|
|
2649
|
+
function visit(type) {
|
|
2650
|
+
if (visited.has(type) || currentlyVisiting.has(type))
|
|
2651
|
+
return;
|
|
2652
|
+
currentlyVisiting.add(type);
|
|
2653
|
+
const deps = dependencyMap.get(type);
|
|
2654
|
+
deps !== void 0 && deps.forEach((dep) => visit(dep)), currentlyVisiting.delete(type), visited.add(type), typeNames.includes(type.name) && typeNames.splice(typeNames.indexOf(type.name), 1), typeNames.unshift(type.name);
|
|
2655
|
+
}
|
|
2656
|
+
for (const [type] of dependencyMap)
|
|
2657
|
+
visit(type);
|
|
2658
|
+
return {
|
|
2659
|
+
sortedSchemaTypeNames: typeNames.filter((typeName) => validSchemaNames.has(typeName)),
|
|
2660
|
+
repeated
|
|
2661
|
+
};
|
|
2662
|
+
}
|
|
2663
|
+
function validateNoCallbacks(typeDef) {
|
|
2016
2664
|
const problems = [];
|
|
2017
|
-
return
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2665
|
+
return problems.push(...validateConditionalProperties(typeDef)), problems.push(...validateValueProperties(typeDef)), problems.push(...validateComponents(typeDef)), problems.push(...validateOptions(typeDef)), problems.push(...validateFieldsetsAndGroups(typeDef)), problems.push(...validateBlockSpecific(typeDef)), problems;
|
|
2666
|
+
}
|
|
2667
|
+
function validateConditionalProperties(typeDef) {
|
|
2668
|
+
const problems = [];
|
|
2669
|
+
return typeof typeDef.hidden == "function" && problems.push(
|
|
2670
|
+
error('The "hidden" property cannot be a function. Use a static boolean value instead.')
|
|
2671
|
+
), typeof typeDef.readOnly == "function" && problems.push(
|
|
2672
|
+
error('The "readOnly" property cannot be a function. Use a static boolean value instead.')
|
|
2673
|
+
), problems;
|
|
2674
|
+
}
|
|
2675
|
+
function validateValueProperties(typeDef) {
|
|
2676
|
+
const problems = [];
|
|
2677
|
+
return typeof typeDef.initialValue == "function" && problems.push(
|
|
2678
|
+
error('The "initialValue" property cannot be a function. Use a static value instead.')
|
|
2679
|
+
), typeof typeDef.validation == "function" && problems.push(
|
|
2680
|
+
error('The "validation" property cannot be a function. Use static validation rules instead.')
|
|
2681
|
+
), typeDef.validation && typeof typeDef.validation == "object" && checkForCustomValidators(typeDef.validation) && problems.push(
|
|
2682
|
+
error("Custom validation functions are not supported. Use only built-in validation rules.")
|
|
2683
|
+
), typeDef.preview?.prepare && typeof typeDef.preview.prepare == "function" && problems.push(error('The "preview.prepare" property cannot be a function.')), typeDef.blockEditor?.render && problems.push(error('The "blockEditor.render" property cannot be a function.')), problems;
|
|
2684
|
+
}
|
|
2685
|
+
function validateComponents(typeDef) {
|
|
2686
|
+
const problems = [];
|
|
2687
|
+
if (!typeDef.components)
|
|
2688
|
+
return problems;
|
|
2689
|
+
const componentProps = [
|
|
2690
|
+
"input",
|
|
2691
|
+
"field",
|
|
2692
|
+
"item",
|
|
2693
|
+
"preview",
|
|
2694
|
+
"diff",
|
|
2695
|
+
"block",
|
|
2696
|
+
"inlineBlock",
|
|
2697
|
+
"annotation"
|
|
2698
|
+
];
|
|
2699
|
+
for (const prop of componentProps)
|
|
2700
|
+
typeDef.components[prop] && isComponentLike(typeDef.components[prop]) && problems.push(error(`The "components.${prop}" property cannot be a component function.`));
|
|
2701
|
+
return typeDef.components.portableText?.plugins && problems.push(
|
|
2702
|
+
error('The "components.portableText.plugins" property cannot contain plugin functions.')
|
|
2703
|
+
), problems;
|
|
2704
|
+
}
|
|
2705
|
+
function validateOptions(typeDef) {
|
|
2706
|
+
const problems = [];
|
|
2707
|
+
return !typeDef.options || typeof typeDef.options != "object" || (problems.push(...validateCommonOptions(typeDef.options)), problems.push(...validateAssetSources(typeDef.options)), problems.push(...validateOtherFunctionOptions(typeDef.options))), problems;
|
|
2708
|
+
}
|
|
2709
|
+
function validateCommonOptions(options) {
|
|
2710
|
+
const problems = [];
|
|
2711
|
+
return typeof options.filter == "function" && problems.push(
|
|
2023
2712
|
error(
|
|
2024
|
-
|
|
2025
|
-
HELP_IDS.TYPE_NAME_RESERVED
|
|
2713
|
+
'The "options.filter" property cannot be a function. Use a static GROQ filter string with filterParams instead.'
|
|
2026
2714
|
)
|
|
2027
|
-
)
|
|
2715
|
+
), typeof options.source == "function" && problems.push(
|
|
2028
2716
|
error(
|
|
2029
|
-
|
|
2717
|
+
'The "options.source" property cannot be a function. Use a static string path instead.'
|
|
2030
2718
|
)
|
|
2031
|
-
), problems.push(
|
|
2032
|
-
...typeDef,
|
|
2033
|
-
_problems: problems
|
|
2034
|
-
};
|
|
2035
|
-
};
|
|
2036
|
-
function looksLikeEsmModule(typeDef) {
|
|
2037
|
-
return !typeDef.name && typeDef.default && (typeDef.default.name || typeDef.default.title);
|
|
2719
|
+
), typeof options.slugify == "function" && problems.push(error('The "options.slugify" property cannot be a function.')), typeof options.isUnique == "function" && problems.push(error('The "options.isUnique" property cannot be a function.')), problems;
|
|
2038
2720
|
}
|
|
2039
|
-
|
|
2721
|
+
function validateAssetSources(options) {
|
|
2040
2722
|
const problems = [];
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
)
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
|
-
array,
|
|
2053
|
-
object,
|
|
2054
|
-
slug,
|
|
2055
|
-
file,
|
|
2056
|
-
image,
|
|
2057
|
-
block: validateBlockType,
|
|
2058
|
-
document: documentVisitor,
|
|
2059
|
-
reference,
|
|
2060
|
-
crossDatasetReference,
|
|
2061
|
-
globalDocumentReference
|
|
2062
|
-
}, getNoopVisitor = (visitorContext) => (schemaDef) => ({
|
|
2063
|
-
name: `<unnamed_type_@_index_${visitorContext.index}>`,
|
|
2064
|
-
...schemaDef,
|
|
2065
|
-
_problems: []
|
|
2066
|
-
});
|
|
2067
|
-
function combine(...visitors) {
|
|
2068
|
-
return (schemaType, visitorContext) => visitors.reduce(
|
|
2069
|
-
(result, visitor) => {
|
|
2070
|
-
const res = visitor(result, visitorContext);
|
|
2071
|
-
return {
|
|
2072
|
-
...res,
|
|
2073
|
-
_problems: result._problems.concat(res._problems)
|
|
2074
|
-
};
|
|
2075
|
-
},
|
|
2076
|
-
{ _problems: [], ...schemaType }
|
|
2077
|
-
);
|
|
2723
|
+
if (!Array.isArray(options.sources))
|
|
2724
|
+
return problems;
|
|
2725
|
+
for (let i = 0; i < options.sources.length; i++) {
|
|
2726
|
+
const source = options.sources[i];
|
|
2727
|
+
source && (source.component && isComponentLike(source.component) && problems.push(
|
|
2728
|
+
error(`Asset source at index ${i} has a "component" property that cannot be a function.`)
|
|
2729
|
+
), source.icon && isComponentLike(source.icon) && problems.push(
|
|
2730
|
+
error(`Asset source at index ${i} has an "icon" property that cannot be a component.`)
|
|
2731
|
+
), (typeof source == "function" || source.Uploader) && problems.push(error(`Asset source at index ${i} contains functions or classes.`)));
|
|
2732
|
+
}
|
|
2733
|
+
return problems;
|
|
2078
2734
|
}
|
|
2079
|
-
function
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2735
|
+
function validateOtherFunctionOptions(options) {
|
|
2736
|
+
const problems = [], knownFunctionOptions = ["filter", "source", "slugify", "isUnique"];
|
|
2737
|
+
for (const [key, value] of Object.entries(options))
|
|
2738
|
+
typeof value == "function" && !knownFunctionOptions.includes(key) && problems.push(error(`The "options.${key}" property cannot be a function.`));
|
|
2739
|
+
return problems;
|
|
2740
|
+
}
|
|
2741
|
+
function validateFieldsetsAndGroups(typeDef) {
|
|
2742
|
+
const problems = [];
|
|
2743
|
+
return problems.push(...validateFieldsets(typeDef.fieldsets)), problems.push(...validateGroups(typeDef.groups)), problems;
|
|
2744
|
+
}
|
|
2745
|
+
function validateFieldsets(fieldsets) {
|
|
2746
|
+
const problems = [];
|
|
2747
|
+
if (!Array.isArray(fieldsets))
|
|
2748
|
+
return problems;
|
|
2749
|
+
for (let i = 0; i < fieldsets.length; i++) {
|
|
2750
|
+
const fieldset = fieldsets[i];
|
|
2751
|
+
fieldset && (typeof fieldset.hidden == "function" && problems.push(
|
|
2752
|
+
error(`Fieldset at index ${i} has a "hidden" property that cannot be a function.`)
|
|
2753
|
+
), typeof fieldset.readOnly == "function" && problems.push(
|
|
2754
|
+
error(`Fieldset at index ${i} has a "readOnly" property that cannot be a function.`)
|
|
2755
|
+
));
|
|
2756
|
+
}
|
|
2757
|
+
return problems;
|
|
2758
|
+
}
|
|
2759
|
+
function validateGroups(groups) {
|
|
2760
|
+
const problems = [];
|
|
2761
|
+
if (!Array.isArray(groups))
|
|
2762
|
+
return problems;
|
|
2763
|
+
for (let i = 0; i < groups.length; i++) {
|
|
2764
|
+
const group = groups[i];
|
|
2765
|
+
group && (typeof group.hidden == "function" && problems.push(
|
|
2766
|
+
error(`Field group at index ${i} has a "hidden" property that cannot be a function.`)
|
|
2767
|
+
), group.icon && isComponentLike(group.icon) && problems.push(
|
|
2768
|
+
error(`Field group at index ${i} has an "icon" property that cannot be a component.`)
|
|
2769
|
+
));
|
|
2770
|
+
}
|
|
2771
|
+
return problems;
|
|
2772
|
+
}
|
|
2773
|
+
function validateBlockSpecific(typeDef) {
|
|
2774
|
+
const problems = [];
|
|
2775
|
+
return typeDef.type !== "block" || (problems.push(...validateBlockStyles(typeDef.styles)), problems.push(...validateBlockMarks(typeDef.marks))), problems;
|
|
2776
|
+
}
|
|
2777
|
+
function validateBlockStyles(styles) {
|
|
2778
|
+
const problems = [];
|
|
2779
|
+
if (!Array.isArray(styles))
|
|
2780
|
+
return problems;
|
|
2781
|
+
for (let i = 0; i < styles.length; i++) {
|
|
2782
|
+
const style = styles[i];
|
|
2783
|
+
style?.component && isComponentLike(style.component) && problems.push(
|
|
2784
|
+
error(`Block style at index ${i} has a "component" property that cannot be a function.`)
|
|
2785
|
+
);
|
|
2786
|
+
}
|
|
2787
|
+
return problems;
|
|
2788
|
+
}
|
|
2789
|
+
function validateBlockMarks(marks) {
|
|
2790
|
+
const problems = [];
|
|
2791
|
+
if (!marks)
|
|
2792
|
+
return problems;
|
|
2793
|
+
if (Array.isArray(marks.decorators))
|
|
2794
|
+
for (let i = 0; i < marks.decorators.length; i++) {
|
|
2795
|
+
const decorator = marks.decorators[i];
|
|
2796
|
+
decorator?.component && isComponentLike(decorator.component) && problems.push(
|
|
2797
|
+
error(
|
|
2798
|
+
`Block decorator at index ${i} has a "component" property that cannot be a function.`
|
|
2799
|
+
)
|
|
2800
|
+
);
|
|
2801
|
+
}
|
|
2802
|
+
if (Array.isArray(marks.annotations))
|
|
2803
|
+
for (let i = 0; i < marks.annotations.length; i++) {
|
|
2804
|
+
const annotation = marks.annotations[i];
|
|
2805
|
+
annotation?.component && isComponentLike(annotation.component) && problems.push(
|
|
2806
|
+
error(
|
|
2807
|
+
`Block annotation at index ${i} has a "component" property that cannot be a function.`
|
|
2808
|
+
)
|
|
2809
|
+
);
|
|
2810
|
+
}
|
|
2811
|
+
return problems;
|
|
2812
|
+
}
|
|
2813
|
+
function checkForCustomValidators(validation) {
|
|
2814
|
+
if (!validation) return !1;
|
|
2815
|
+
if (Array.isArray(validation))
|
|
2816
|
+
return validation.some((v) => checkForCustomValidators(v));
|
|
2817
|
+
if (typeof validation == "object") {
|
|
2818
|
+
if (Array.isArray(validation._rules))
|
|
2819
|
+
return validation._rules.some((rule) => rule.flag === "custom" && typeof rule.constraint == "function");
|
|
2820
|
+
if (typeof validation.custom == "function")
|
|
2821
|
+
return !0;
|
|
2822
|
+
}
|
|
2823
|
+
return !1;
|
|
2084
2824
|
}
|
|
2085
2825
|
function unsupportedTypeValidator(typeLabel) {
|
|
2086
2826
|
return function() {
|
|
@@ -2094,8 +2834,15 @@ function unsupportedTypeValidator(typeLabel) {
|
|
|
2094
2834
|
};
|
|
2095
2835
|
};
|
|
2096
2836
|
}
|
|
2837
|
+
function noCallbacksVisitor(typeDef, visitorContext) {
|
|
2838
|
+
return {
|
|
2839
|
+
...typeDef,
|
|
2840
|
+
_problems: validateNoCallbacks(typeDef)
|
|
2841
|
+
};
|
|
2842
|
+
}
|
|
2097
2843
|
function validateMediaLibraryAssetAspect(maybeAspect) {
|
|
2098
2844
|
const validated = validateSchema([maybeAspect], {
|
|
2845
|
+
transformCommonVisitors: (visitors) => [...visitors, noCallbacksVisitor],
|
|
2099
2846
|
transformTypeVisitors: (typeVisitors2) => ({
|
|
2100
2847
|
...typeVisitors2,
|
|
2101
2848
|
document: unsupportedTypeValidator("document"),
|
|
@@ -2108,15 +2855,20 @@ function validateMediaLibraryAssetAspect(maybeAspect) {
|
|
|
2108
2855
|
}), errors = groupProblems(validated.getTypes()).map((group) => group.problems.filter(({ severity }) => severity === "error")).filter((problems) => problems.length);
|
|
2109
2856
|
return [errors.length === 0, errors];
|
|
2110
2857
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2858
|
+
export {
|
|
2859
|
+
ALL_FIELDS_GROUP_NAME,
|
|
2860
|
+
DEFAULT_MAX_FIELD_DEPTH,
|
|
2861
|
+
DescriptorConverter,
|
|
2862
|
+
ValidationError,
|
|
2863
|
+
builtinTypes,
|
|
2864
|
+
createSchemaFromManifestTypes,
|
|
2865
|
+
extractSchema,
|
|
2866
|
+
groupProblems,
|
|
2867
|
+
isActionEnabled,
|
|
2868
|
+
processSchemaSynchronization,
|
|
2869
|
+
resolveSearchConfig,
|
|
2870
|
+
resolveSearchConfigForBaseFieldPaths,
|
|
2871
|
+
validateMediaLibraryAssetAspect,
|
|
2872
|
+
validateSchema
|
|
2873
|
+
};
|
|
2122
2874
|
//# sourceMappingURL=_internal.js.map
|