@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.mjs
DELETED
|
@@ -1,2131 +0,0 @@
|
|
|
1
|
-
import { SetBuilder, processSetSynchronization } from "@sanity/descriptors";
|
|
2
|
-
import { OWN_PROPS_NAME } from "./_chunks-es/resolve.mjs";
|
|
3
|
-
import { DEFAULT_MAX_FIELD_DEPTH, resolveSearchConfig, resolveSearchConfigForBaseFieldPaths } from "./_chunks-es/resolve.mjs";
|
|
4
|
-
import difference from "lodash/difference.js";
|
|
5
|
-
import { createReferenceTypeNode } from "groq-js";
|
|
6
|
-
import flatten from "lodash/flatten.js";
|
|
7
|
-
import get from "lodash/get.js";
|
|
8
|
-
import uniq from "lodash/uniq.js";
|
|
9
|
-
import humanizeList from "humanize-list";
|
|
10
|
-
import partition from "lodash/partition.js";
|
|
11
|
-
import isPlainObject from "lodash/isPlainObject.js";
|
|
12
|
-
import omit from "lodash/omit.js";
|
|
13
|
-
import leven from "leven";
|
|
14
|
-
import inspect from "object-inspect";
|
|
15
|
-
const MAX_DEPTH_UKNOWN = 5;
|
|
16
|
-
class DescriptorConverter {
|
|
17
|
-
opts;
|
|
18
|
-
cache = /* @__PURE__ */ new WeakMap();
|
|
19
|
-
constructor(opts) {
|
|
20
|
-
this.opts = opts;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Returns a synchronization object for a schema.
|
|
24
|
-
*
|
|
25
|
-
* This is automatically cached in a weak map.
|
|
26
|
-
*/
|
|
27
|
-
get(schema) {
|
|
28
|
-
let value = this.cache.get(schema);
|
|
29
|
-
if (value) return value;
|
|
30
|
-
const builder = new SetBuilder();
|
|
31
|
-
for (const name of schema.getLocalTypeNames()) {
|
|
32
|
-
const typeDef = convertTypeDef(schema.get(name));
|
|
33
|
-
builder.addObject("sanity.schema.namedType", { name, typeDef });
|
|
34
|
-
}
|
|
35
|
-
return schema.parent && builder.addSet(this.get(schema.parent)), value = builder.build("sanity.schema.registry"), this.cache.set(schema, value), value;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function convertCommonTypeDef(schemaType, opts) {
|
|
39
|
-
const ownProps = OWN_PROPS_NAME in schemaType ? schemaType[OWN_PROPS_NAME] : schemaType;
|
|
40
|
-
let fields;
|
|
41
|
-
Array.isArray(ownProps.fields) && (fields = ownProps.fields.map(
|
|
42
|
-
({ name, group, fieldset, type }) => ({
|
|
43
|
-
name,
|
|
44
|
-
typeDef: convertTypeDef(type),
|
|
45
|
-
groups: arrayifyString(group),
|
|
46
|
-
fieldset
|
|
47
|
-
})
|
|
48
|
-
));
|
|
49
|
-
let fieldsets;
|
|
50
|
-
Array.isArray(ownProps.fieldsets) && (fieldsets = filterStringKey(
|
|
51
|
-
"name",
|
|
52
|
-
ownProps.fieldsets.map(
|
|
53
|
-
({ name, title, description, group, hidden, readOnly, options }) => ({
|
|
54
|
-
name,
|
|
55
|
-
title: maybeString(title),
|
|
56
|
-
description: maybeString(description),
|
|
57
|
-
group: maybeString(group),
|
|
58
|
-
hidden: conditionalTrue(hidden),
|
|
59
|
-
readOnly: conditionalTrue(readOnly),
|
|
60
|
-
options: convertUnknown(options)
|
|
61
|
-
})
|
|
62
|
-
)
|
|
63
|
-
));
|
|
64
|
-
let groups;
|
|
65
|
-
Array.isArray(ownProps.groups) && (groups = filterStringKey(
|
|
66
|
-
"name",
|
|
67
|
-
ownProps.groups.map(
|
|
68
|
-
({ name, title, hidden, default: def }) => ({
|
|
69
|
-
name,
|
|
70
|
-
title: maybeString(title),
|
|
71
|
-
hidden: conditionalTrue(hidden),
|
|
72
|
-
default: maybeTrue(def)
|
|
73
|
-
})
|
|
74
|
-
)
|
|
75
|
-
));
|
|
76
|
-
const reason = ownProps.deprecated?.reason;
|
|
77
|
-
return {
|
|
78
|
-
title: maybeString(ownProps.title),
|
|
79
|
-
description: maybeStringOrJSX(ownProps.description),
|
|
80
|
-
readOnly: conditionalTrue(ownProps.readOnly),
|
|
81
|
-
hidden: conditionalTrue(ownProps.hidden),
|
|
82
|
-
liveEdit: maybeTrue(ownProps.liveEdit),
|
|
83
|
-
options: convertUnknown(ownProps.options),
|
|
84
|
-
initialValue: convertUnknown(ownProps.initialValue),
|
|
85
|
-
deprecated: typeof reason == "string" ? { reason } : void 0,
|
|
86
|
-
placeholder: maybeString(ownProps.placeholder),
|
|
87
|
-
rows: maybeNumberAsString(ownProps.rows),
|
|
88
|
-
fields,
|
|
89
|
-
fieldsets,
|
|
90
|
-
groups
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function convertTypeDef(schemaType, opts) {
|
|
94
|
-
const common2 = convertCommonTypeDef(schemaType);
|
|
95
|
-
if (!schemaType.type)
|
|
96
|
-
return {
|
|
97
|
-
extends: null,
|
|
98
|
-
jsonType: schemaType.jsonType,
|
|
99
|
-
...common2
|
|
100
|
-
};
|
|
101
|
-
switch (schemaType.type.name) {
|
|
102
|
-
case "array":
|
|
103
|
-
return {
|
|
104
|
-
extends: "array",
|
|
105
|
-
of: schemaType.of.map((ofType) => ({
|
|
106
|
-
name: ofType.name,
|
|
107
|
-
typeDef: convertTypeDef(ofType)
|
|
108
|
-
})),
|
|
109
|
-
...common2
|
|
110
|
-
};
|
|
111
|
-
case "reference":
|
|
112
|
-
case "globalDocumentReference":
|
|
113
|
-
case "crossDatasetReference":
|
|
114
|
-
return {
|
|
115
|
-
extends: schemaType.type.name,
|
|
116
|
-
to: filterStringKey(
|
|
117
|
-
"name",
|
|
118
|
-
schemaType.to.map((toType) => ({ name: toType.name || toType.type?.name || toType.type }))
|
|
119
|
-
),
|
|
120
|
-
...common2
|
|
121
|
-
};
|
|
122
|
-
default:
|
|
123
|
-
return { extends: schemaType.type.name, ...common2 };
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
function maybeString(val) {
|
|
127
|
-
return typeof val == "string" ? val : void 0;
|
|
128
|
-
}
|
|
129
|
-
function maybeNumberAsString(val) {
|
|
130
|
-
return typeof val == "number" ? val.toString() : void 0;
|
|
131
|
-
}
|
|
132
|
-
function maybeTrue(val) {
|
|
133
|
-
return val === !0 ? !0 : void 0;
|
|
134
|
-
}
|
|
135
|
-
function conditionalTrue(val) {
|
|
136
|
-
return typeof val == "function" ? FUNCTION_MARKER : maybeTrue(val);
|
|
137
|
-
}
|
|
138
|
-
function filterStringKey(key, arr) {
|
|
139
|
-
return arr.filter((obj) => typeof obj[key] == "string");
|
|
140
|
-
}
|
|
141
|
-
function arrayifyString(val) {
|
|
142
|
-
if (typeof val == "string")
|
|
143
|
-
return [val];
|
|
144
|
-
if (Array.isArray(val))
|
|
145
|
-
return val.filter((elem) => typeof elem == "string");
|
|
146
|
-
}
|
|
147
|
-
const FUNCTION_MARKER = { __type: "function" }, UNKNOWN_MARKER = { __type: "unknown" }, UNDEFINED_MARKER = { __type: "undefined" }, CYCLIC_MARKER = { __type: "cyclic" }, MAX_DEPTH_MARKER = { __type: "maxDepth" };
|
|
148
|
-
function convertUnknown(val, seen = /* @__PURE__ */ new Set(), maxDepth = MAX_DEPTH_UKNOWN) {
|
|
149
|
-
if (maxDepth === 0) return MAX_DEPTH_MARKER;
|
|
150
|
-
if (typeof val == "string" || typeof val == "boolean" || val === null || val === void 0)
|
|
151
|
-
return val;
|
|
152
|
-
if (typeof val == "number")
|
|
153
|
-
return { __type: "number", value: val.toString() };
|
|
154
|
-
if (typeof val == "function") return FUNCTION_MARKER;
|
|
155
|
-
if (seen.has(val))
|
|
156
|
-
return CYCLIC_MARKER;
|
|
157
|
-
if (seen.add(val), typeof val == "object") {
|
|
158
|
-
if (Array.isArray(val))
|
|
159
|
-
return val.map((elem) => {
|
|
160
|
-
const res = convertUnknown(elem, seen, maxDepth - 1);
|
|
161
|
-
return res === void 0 ? UNDEFINED_MARKER : res;
|
|
162
|
-
});
|
|
163
|
-
if ("$$typeof" in val && "type" in val && "props" in val) {
|
|
164
|
-
const { type, props } = val, strType = typeof type == "function" ? type.name : type;
|
|
165
|
-
return typeof strType != "string" ? void 0 : {
|
|
166
|
-
__type: "jsx",
|
|
167
|
-
type: strType,
|
|
168
|
-
props: convertUnknown(props, seen, maxDepth - 1)
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
let hasType = !1;
|
|
172
|
-
const result = {};
|
|
173
|
-
for (const [key, field] of Object.entries(val))
|
|
174
|
-
key === "__type" && (hasType = !0), result[key] = convertUnknown(field, seen, maxDepth - 1);
|
|
175
|
-
return hasType ? { __type: "object", value: result } : result;
|
|
176
|
-
}
|
|
177
|
-
return UNKNOWN_MARKER;
|
|
178
|
-
}
|
|
179
|
-
function maybeStringOrJSX(val) {
|
|
180
|
-
if (typeof val == "string") return val;
|
|
181
|
-
if (val && typeof val == "object" && "$$typeof" in val && "type" in val && "props" in val) {
|
|
182
|
-
const { type, props } = val, strType = typeof type == "function" ? type.name : type;
|
|
183
|
-
return typeof strType != "string" ? void 0 : { __type: "jsx", type: strType, props: convertUnknown(props) };
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
function processSchemaSynchronization(sync, response) {
|
|
187
|
-
return processSetSynchronization(sync, response);
|
|
188
|
-
}
|
|
189
|
-
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) => {
|
|
190
|
-
if (!Array.isArray(actions))
|
|
191
|
-
throw new Error(
|
|
192
|
-
`The value of <type>.${ACTIONS_FLAG} should be an array with any of the actions ${VALID_ACTIONS.join(
|
|
193
|
-
", "
|
|
194
|
-
)}`
|
|
195
|
-
);
|
|
196
|
-
const invalid = difference(actions, VALID_ACTIONS);
|
|
197
|
-
if (invalid.length > 0)
|
|
198
|
-
throw new Error(
|
|
199
|
-
`Invalid action${invalid.length > 1 ? "s" : ""} configured for schema type "${typeName}": ${invalid.join(
|
|
200
|
-
", "
|
|
201
|
-
)}. Valid actions are: ${VALID_ACTIONS.join(", ")}`
|
|
202
|
-
);
|
|
203
|
-
return actions;
|
|
204
|
-
}, resolveEnabledActions = (schemaType) => validateActions(schemaType.name, readActions(schemaType)), isActionEnabled = (schemaType, action) => resolveEnabledActions(schemaType).includes(action);
|
|
205
|
-
var assetSourceData = {
|
|
206
|
-
name: "sanity.assetSourceData",
|
|
207
|
-
title: "Asset Source Data",
|
|
208
|
-
type: "object",
|
|
209
|
-
fields: [
|
|
210
|
-
{
|
|
211
|
-
name: "name",
|
|
212
|
-
title: "Source name",
|
|
213
|
-
description: "A canonical name for the source this asset is originating from",
|
|
214
|
-
type: "string"
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name: "id",
|
|
218
|
-
title: "Asset Source ID",
|
|
219
|
-
description: "The unique ID for the asset within the originating source so you can programatically find back to it",
|
|
220
|
-
type: "string"
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
name: "url",
|
|
224
|
-
title: "Asset information URL",
|
|
225
|
-
description: "A URL to find more information about this asset in the originating source",
|
|
226
|
-
type: "string"
|
|
227
|
-
}
|
|
228
|
-
]
|
|
229
|
-
}, fileAsset = {
|
|
230
|
-
name: "sanity.fileAsset",
|
|
231
|
-
title: "File",
|
|
232
|
-
type: "document",
|
|
233
|
-
fieldsets: [
|
|
234
|
-
{
|
|
235
|
-
name: "system",
|
|
236
|
-
title: "System fields",
|
|
237
|
-
description: "These fields are managed by the system and not editable"
|
|
238
|
-
}
|
|
239
|
-
],
|
|
240
|
-
fields: [
|
|
241
|
-
{
|
|
242
|
-
name: "originalFilename",
|
|
243
|
-
type: "string",
|
|
244
|
-
title: "Original file name",
|
|
245
|
-
readOnly: !0
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
name: "label",
|
|
249
|
-
type: "string",
|
|
250
|
-
title: "Label"
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
name: "title",
|
|
254
|
-
type: "string",
|
|
255
|
-
title: "Title"
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
name: "description",
|
|
259
|
-
type: "string",
|
|
260
|
-
title: "Description"
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
name: "altText",
|
|
264
|
-
type: "string",
|
|
265
|
-
title: "Alternative text"
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
name: "sha1hash",
|
|
269
|
-
type: "string",
|
|
270
|
-
title: "SHA1 hash",
|
|
271
|
-
readOnly: !0,
|
|
272
|
-
fieldset: "system"
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
name: "extension",
|
|
276
|
-
type: "string",
|
|
277
|
-
title: "File extension",
|
|
278
|
-
readOnly: !0,
|
|
279
|
-
fieldset: "system"
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
name: "mimeType",
|
|
283
|
-
type: "string",
|
|
284
|
-
title: "Mime type",
|
|
285
|
-
readOnly: !0,
|
|
286
|
-
fieldset: "system"
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
name: "size",
|
|
290
|
-
type: "number",
|
|
291
|
-
title: "File size in bytes",
|
|
292
|
-
readOnly: !0,
|
|
293
|
-
fieldset: "system"
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
name: "assetId",
|
|
297
|
-
type: "string",
|
|
298
|
-
title: "Asset ID",
|
|
299
|
-
readOnly: !0,
|
|
300
|
-
fieldset: "system"
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
name: "uploadId",
|
|
304
|
-
type: "string",
|
|
305
|
-
readOnly: !0,
|
|
306
|
-
hidden: !0,
|
|
307
|
-
fieldset: "system"
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
name: "path",
|
|
311
|
-
type: "string",
|
|
312
|
-
title: "Path",
|
|
313
|
-
readOnly: !0,
|
|
314
|
-
fieldset: "system"
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
name: "url",
|
|
318
|
-
type: "string",
|
|
319
|
-
title: "Url",
|
|
320
|
-
readOnly: !0,
|
|
321
|
-
fieldset: "system"
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
name: "source",
|
|
325
|
-
type: "sanity.assetSourceData",
|
|
326
|
-
title: "Source",
|
|
327
|
-
readOnly: !0,
|
|
328
|
-
fieldset: "system"
|
|
329
|
-
}
|
|
330
|
-
],
|
|
331
|
-
preview: {
|
|
332
|
-
select: {
|
|
333
|
-
title: "originalFilename",
|
|
334
|
-
path: "path",
|
|
335
|
-
mimeType: "mimeType",
|
|
336
|
-
size: "size"
|
|
337
|
-
},
|
|
338
|
-
prepare(doc) {
|
|
339
|
-
return {
|
|
340
|
-
title: doc.title || doc.path.split("/").slice(-1)[0],
|
|
341
|
-
subtitle: `${doc.mimeType} (${(doc.size / 1024 / 1024).toFixed(2)} MB)`
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
},
|
|
345
|
-
orderings: [
|
|
346
|
-
{
|
|
347
|
-
title: "File size",
|
|
348
|
-
name: "fileSizeDesc",
|
|
349
|
-
by: [{ field: "size", direction: "desc" }]
|
|
350
|
-
}
|
|
351
|
-
]
|
|
352
|
-
}, geopoint = {
|
|
353
|
-
title: "Geographical Point",
|
|
354
|
-
name: "geopoint",
|
|
355
|
-
type: "object",
|
|
356
|
-
fields: [
|
|
357
|
-
{
|
|
358
|
-
name: "lat",
|
|
359
|
-
type: "number",
|
|
360
|
-
title: "Latitude"
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
name: "lng",
|
|
364
|
-
type: "number",
|
|
365
|
-
title: "Longitude"
|
|
366
|
-
},
|
|
367
|
-
{
|
|
368
|
-
name: "alt",
|
|
369
|
-
type: "number",
|
|
370
|
-
title: "Altitude"
|
|
371
|
-
}
|
|
372
|
-
]
|
|
373
|
-
}, imageAsset = {
|
|
374
|
-
name: "sanity.imageAsset",
|
|
375
|
-
title: "Image",
|
|
376
|
-
type: "document",
|
|
377
|
-
fieldsets: [
|
|
378
|
-
{
|
|
379
|
-
name: "system",
|
|
380
|
-
title: "System fields",
|
|
381
|
-
description: "These fields are managed by the system and not editable"
|
|
382
|
-
}
|
|
383
|
-
],
|
|
384
|
-
fields: [
|
|
385
|
-
{
|
|
386
|
-
name: "originalFilename",
|
|
387
|
-
type: "string",
|
|
388
|
-
title: "Original file name",
|
|
389
|
-
readOnly: !0
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
name: "label",
|
|
393
|
-
type: "string",
|
|
394
|
-
title: "Label"
|
|
395
|
-
},
|
|
396
|
-
{
|
|
397
|
-
name: "title",
|
|
398
|
-
type: "string",
|
|
399
|
-
title: "Title"
|
|
400
|
-
},
|
|
401
|
-
{
|
|
402
|
-
name: "description",
|
|
403
|
-
type: "string",
|
|
404
|
-
title: "Description"
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
name: "altText",
|
|
408
|
-
type: "string",
|
|
409
|
-
title: "Alternative text"
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
name: "sha1hash",
|
|
413
|
-
type: "string",
|
|
414
|
-
title: "SHA1 hash",
|
|
415
|
-
readOnly: !0,
|
|
416
|
-
fieldset: "system"
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
name: "extension",
|
|
420
|
-
type: "string",
|
|
421
|
-
readOnly: !0,
|
|
422
|
-
title: "File extension",
|
|
423
|
-
fieldset: "system"
|
|
424
|
-
},
|
|
425
|
-
{
|
|
426
|
-
name: "mimeType",
|
|
427
|
-
type: "string",
|
|
428
|
-
readOnly: !0,
|
|
429
|
-
title: "Mime type",
|
|
430
|
-
fieldset: "system"
|
|
431
|
-
},
|
|
432
|
-
{
|
|
433
|
-
name: "size",
|
|
434
|
-
type: "number",
|
|
435
|
-
title: "File size in bytes",
|
|
436
|
-
readOnly: !0,
|
|
437
|
-
fieldset: "system"
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
name: "assetId",
|
|
441
|
-
type: "string",
|
|
442
|
-
title: "Asset ID",
|
|
443
|
-
readOnly: !0,
|
|
444
|
-
fieldset: "system"
|
|
445
|
-
},
|
|
446
|
-
{
|
|
447
|
-
name: "uploadId",
|
|
448
|
-
type: "string",
|
|
449
|
-
readOnly: !0,
|
|
450
|
-
hidden: !0,
|
|
451
|
-
fieldset: "system"
|
|
452
|
-
},
|
|
453
|
-
{
|
|
454
|
-
name: "path",
|
|
455
|
-
type: "string",
|
|
456
|
-
title: "Path",
|
|
457
|
-
readOnly: !0,
|
|
458
|
-
fieldset: "system"
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
name: "url",
|
|
462
|
-
type: "string",
|
|
463
|
-
title: "Url",
|
|
464
|
-
readOnly: !0,
|
|
465
|
-
fieldset: "system"
|
|
466
|
-
},
|
|
467
|
-
{
|
|
468
|
-
name: "metadata",
|
|
469
|
-
type: "sanity.imageMetadata",
|
|
470
|
-
title: "Metadata"
|
|
471
|
-
},
|
|
472
|
-
{
|
|
473
|
-
name: "source",
|
|
474
|
-
type: "sanity.assetSourceData",
|
|
475
|
-
title: "Source",
|
|
476
|
-
readOnly: !0,
|
|
477
|
-
fieldset: "system"
|
|
478
|
-
}
|
|
479
|
-
],
|
|
480
|
-
preview: {
|
|
481
|
-
select: {
|
|
482
|
-
id: "_id",
|
|
483
|
-
title: "originalFilename",
|
|
484
|
-
mimeType: "mimeType",
|
|
485
|
-
size: "size"
|
|
486
|
-
},
|
|
487
|
-
prepare(doc) {
|
|
488
|
-
return {
|
|
489
|
-
title: doc.title || typeof doc.path == "string" && doc.path.split("/").slice(-1)[0],
|
|
490
|
-
media: { asset: { _ref: doc.id } },
|
|
491
|
-
subtitle: `${doc.mimeType} (${(Number(doc.size) / 1024 / 1024).toFixed(2)} MB)`
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
},
|
|
495
|
-
orderings: [
|
|
496
|
-
{
|
|
497
|
-
title: "File size",
|
|
498
|
-
name: "fileSizeDesc",
|
|
499
|
-
by: [{ field: "size", direction: "desc" }]
|
|
500
|
-
}
|
|
501
|
-
]
|
|
502
|
-
}, imageCrop = {
|
|
503
|
-
name: "sanity.imageCrop",
|
|
504
|
-
title: "Image crop",
|
|
505
|
-
type: "object",
|
|
506
|
-
fields: [
|
|
507
|
-
{
|
|
508
|
-
name: "top",
|
|
509
|
-
type: "number"
|
|
510
|
-
},
|
|
511
|
-
{
|
|
512
|
-
name: "bottom",
|
|
513
|
-
type: "number"
|
|
514
|
-
},
|
|
515
|
-
{
|
|
516
|
-
name: "left",
|
|
517
|
-
type: "number"
|
|
518
|
-
},
|
|
519
|
-
{
|
|
520
|
-
name: "right",
|
|
521
|
-
type: "number"
|
|
522
|
-
}
|
|
523
|
-
]
|
|
524
|
-
}, imageDimensions = {
|
|
525
|
-
name: "sanity.imageDimensions",
|
|
526
|
-
type: "object",
|
|
527
|
-
title: "Image dimensions",
|
|
528
|
-
fields: [
|
|
529
|
-
{ name: "height", type: "number", title: "Height", readOnly: !0 },
|
|
530
|
-
{ name: "width", type: "number", title: "Width", readOnly: !0 },
|
|
531
|
-
{ name: "aspectRatio", type: "number", title: "Aspect ratio", readOnly: !0 }
|
|
532
|
-
]
|
|
533
|
-
}, imageHotspot = {
|
|
534
|
-
name: "sanity.imageHotspot",
|
|
535
|
-
title: "Image hotspot",
|
|
536
|
-
type: "object",
|
|
537
|
-
fields: [
|
|
538
|
-
{
|
|
539
|
-
name: "x",
|
|
540
|
-
type: "number"
|
|
541
|
-
},
|
|
542
|
-
{
|
|
543
|
-
name: "y",
|
|
544
|
-
type: "number"
|
|
545
|
-
},
|
|
546
|
-
{
|
|
547
|
-
name: "height",
|
|
548
|
-
type: "number"
|
|
549
|
-
},
|
|
550
|
-
{
|
|
551
|
-
name: "width",
|
|
552
|
-
type: "number"
|
|
553
|
-
}
|
|
554
|
-
]
|
|
555
|
-
}, imageMetadata = {
|
|
556
|
-
name: "sanity.imageMetadata",
|
|
557
|
-
title: "Image metadata",
|
|
558
|
-
type: "object",
|
|
559
|
-
fieldsets: [
|
|
560
|
-
{
|
|
561
|
-
name: "extra",
|
|
562
|
-
title: "Extra metadata\u2026",
|
|
563
|
-
options: {
|
|
564
|
-
collapsable: !0
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
],
|
|
568
|
-
fields: [
|
|
569
|
-
{
|
|
570
|
-
name: "location",
|
|
571
|
-
type: "geopoint"
|
|
572
|
-
},
|
|
573
|
-
{
|
|
574
|
-
name: "dimensions",
|
|
575
|
-
title: "Dimensions",
|
|
576
|
-
type: "sanity.imageDimensions",
|
|
577
|
-
fieldset: "extra"
|
|
578
|
-
},
|
|
579
|
-
{
|
|
580
|
-
name: "palette",
|
|
581
|
-
type: "sanity.imagePalette",
|
|
582
|
-
title: "Palette",
|
|
583
|
-
fieldset: "extra"
|
|
584
|
-
},
|
|
585
|
-
{
|
|
586
|
-
name: "lqip",
|
|
587
|
-
title: "LQIP (Low-Quality Image Placeholder)",
|
|
588
|
-
type: "string",
|
|
589
|
-
readOnly: !0
|
|
590
|
-
},
|
|
591
|
-
{
|
|
592
|
-
name: "blurHash",
|
|
593
|
-
title: "BlurHash",
|
|
594
|
-
type: "string",
|
|
595
|
-
readOnly: !0
|
|
596
|
-
},
|
|
597
|
-
{
|
|
598
|
-
name: "hasAlpha",
|
|
599
|
-
title: "Has alpha channel",
|
|
600
|
-
type: "boolean",
|
|
601
|
-
readOnly: !0
|
|
602
|
-
},
|
|
603
|
-
{
|
|
604
|
-
name: "isOpaque",
|
|
605
|
-
title: "Is opaque",
|
|
606
|
-
type: "boolean",
|
|
607
|
-
readOnly: !0
|
|
608
|
-
}
|
|
609
|
-
]
|
|
610
|
-
}, imagePalette = {
|
|
611
|
-
name: "sanity.imagePalette",
|
|
612
|
-
title: "Image palette",
|
|
613
|
-
type: "object",
|
|
614
|
-
fields: [
|
|
615
|
-
{ name: "darkMuted", type: "sanity.imagePaletteSwatch", title: "Dark Muted" },
|
|
616
|
-
{ name: "lightVibrant", type: "sanity.imagePaletteSwatch", title: "Light Vibrant" },
|
|
617
|
-
{ name: "darkVibrant", type: "sanity.imagePaletteSwatch", title: "Dark Vibrant" },
|
|
618
|
-
{ name: "vibrant", type: "sanity.imagePaletteSwatch", title: "Vibrant" },
|
|
619
|
-
{ name: "dominant", type: "sanity.imagePaletteSwatch", title: "Dominant" },
|
|
620
|
-
{ name: "lightMuted", type: "sanity.imagePaletteSwatch", title: "Light Muted" },
|
|
621
|
-
{ name: "muted", type: "sanity.imagePaletteSwatch", title: "Muted" }
|
|
622
|
-
]
|
|
623
|
-
}, imagePaletteSwatch = {
|
|
624
|
-
name: "sanity.imagePaletteSwatch",
|
|
625
|
-
title: "Image palette swatch",
|
|
626
|
-
type: "object",
|
|
627
|
-
fields: [
|
|
628
|
-
{ name: "background", type: "string", title: "Background", readOnly: !0 },
|
|
629
|
-
{ name: "foreground", type: "string", title: "Foreground", readOnly: !0 },
|
|
630
|
-
{ name: "population", type: "number", title: "Population", readOnly: !0 },
|
|
631
|
-
{ name: "title", type: "string", title: "String", readOnly: !0 }
|
|
632
|
-
]
|
|
633
|
-
}, slug$1 = {
|
|
634
|
-
title: "Slug",
|
|
635
|
-
name: "slug",
|
|
636
|
-
type: "object",
|
|
637
|
-
fields: [
|
|
638
|
-
{
|
|
639
|
-
name: "current",
|
|
640
|
-
title: "Current slug",
|
|
641
|
-
type: "string",
|
|
642
|
-
validation: (Rule) => Rule.required()
|
|
643
|
-
},
|
|
644
|
-
{
|
|
645
|
-
// The source field is deprecated/unused, but leaving it included and hidden
|
|
646
|
-
// to prevent rendering "Unknown field" warnings on legacy data
|
|
647
|
-
name: "source",
|
|
648
|
-
title: "Source field",
|
|
649
|
-
type: "string",
|
|
650
|
-
hidden: !0
|
|
651
|
-
}
|
|
652
|
-
]
|
|
653
|
-
};
|
|
654
|
-
const builtinTypes = [
|
|
655
|
-
assetSourceData,
|
|
656
|
-
slug$1,
|
|
657
|
-
geopoint,
|
|
658
|
-
// legacyRichDate,
|
|
659
|
-
imageAsset,
|
|
660
|
-
fileAsset,
|
|
661
|
-
imageCrop,
|
|
662
|
-
imageHotspot,
|
|
663
|
-
imageMetadata,
|
|
664
|
-
imageDimensions,
|
|
665
|
-
imagePalette,
|
|
666
|
-
imagePaletteSwatch
|
|
667
|
-
], documentDefaultFields = (typeName) => ({
|
|
668
|
-
_id: {
|
|
669
|
-
type: "objectAttribute",
|
|
670
|
-
value: { type: "string" }
|
|
671
|
-
},
|
|
672
|
-
_type: {
|
|
673
|
-
type: "objectAttribute",
|
|
674
|
-
value: { type: "string", value: typeName }
|
|
675
|
-
},
|
|
676
|
-
_createdAt: {
|
|
677
|
-
type: "objectAttribute",
|
|
678
|
-
value: { type: "string" }
|
|
679
|
-
},
|
|
680
|
-
_updatedAt: {
|
|
681
|
-
type: "objectAttribute",
|
|
682
|
-
value: { type: "string" }
|
|
683
|
-
},
|
|
684
|
-
_rev: {
|
|
685
|
-
type: "objectAttribute",
|
|
686
|
-
value: { type: "string" }
|
|
687
|
-
}
|
|
688
|
-
}), typesMap = /* @__PURE__ */ new Map([
|
|
689
|
-
["text", { type: "string" }],
|
|
690
|
-
["url", { type: "string" }],
|
|
691
|
-
["datetime", { type: "string" }],
|
|
692
|
-
["date", { type: "string" }],
|
|
693
|
-
["boolean", { type: "boolean" }],
|
|
694
|
-
["email", { type: "string" }]
|
|
695
|
-
]);
|
|
696
|
-
function extractSchema(schemaDef, extractOptions = {}) {
|
|
697
|
-
const inlineFields = /* @__PURE__ */ new Set(), documentTypes = /* @__PURE__ */ new Map(), schema = [];
|
|
698
|
-
sortByDependencies(schemaDef).forEach((typeName) => {
|
|
699
|
-
const schemaType = schemaDef.get(typeName);
|
|
700
|
-
if (schemaType === void 0)
|
|
701
|
-
return;
|
|
702
|
-
const base = convertBaseType(schemaType);
|
|
703
|
-
base !== null && (base.type === "type" && inlineFields.add(schemaType), base.type === "document" && documentTypes.set(typeName, base), schema.push(base));
|
|
704
|
-
});
|
|
705
|
-
function convertBaseType(schemaType) {
|
|
706
|
-
let typeName;
|
|
707
|
-
if (schemaType.type ? typeName = schemaType.type.name : "jsonType" in schemaType && (typeName = schemaType.jsonType), typeName === "document" && isObjectType(schemaType)) {
|
|
708
|
-
const defaultAttributes = documentDefaultFields(schemaType.name), object2 = createObject(schemaType);
|
|
709
|
-
return object2.type === "unknown" ? null : {
|
|
710
|
-
name: schemaType.name,
|
|
711
|
-
type: "document",
|
|
712
|
-
attributes: {
|
|
713
|
-
...defaultAttributes,
|
|
714
|
-
...object2.attributes
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
|
-
}
|
|
718
|
-
const value = convertSchemaType(schemaType);
|
|
719
|
-
return value.type === "unknown" ? null : value.type === "object" ? {
|
|
720
|
-
name: schemaType.name,
|
|
721
|
-
type: "type",
|
|
722
|
-
value: {
|
|
723
|
-
type: "object",
|
|
724
|
-
attributes: {
|
|
725
|
-
_type: {
|
|
726
|
-
type: "objectAttribute",
|
|
727
|
-
value: {
|
|
728
|
-
type: "string",
|
|
729
|
-
value: schemaType.name
|
|
730
|
-
}
|
|
731
|
-
},
|
|
732
|
-
...value.attributes
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
} : {
|
|
736
|
-
name: schemaType.name,
|
|
737
|
-
type: "type",
|
|
738
|
-
value
|
|
739
|
-
};
|
|
740
|
-
}
|
|
741
|
-
function convertSchemaType(schemaType) {
|
|
742
|
-
if (inlineFields.has(schemaType.type))
|
|
743
|
-
return { type: "inline", name: schemaType.type.name };
|
|
744
|
-
if (schemaType.type?.type?.name === "object")
|
|
745
|
-
return { type: "inline", name: schemaType.type.name };
|
|
746
|
-
if (isStringType(schemaType))
|
|
747
|
-
return createStringTypeNodeDefintion(schemaType);
|
|
748
|
-
if (isNumberType(schemaType))
|
|
749
|
-
return createNumberTypeNodeDefintion(schemaType);
|
|
750
|
-
if (schemaType.type && typesMap.has(schemaType.type.name))
|
|
751
|
-
return typesMap.get(schemaType.type.name);
|
|
752
|
-
if (isCrossDatasetReferenceType(schemaType))
|
|
753
|
-
return { type: "unknown" };
|
|
754
|
-
if (isGlobalDocumentReferenceType(schemaType))
|
|
755
|
-
return { type: "unknown" };
|
|
756
|
-
if (isReferenceType(schemaType))
|
|
757
|
-
return createReferenceTypeNodeDefintion(schemaType);
|
|
758
|
-
if (isArrayType(schemaType))
|
|
759
|
-
return createArray(schemaType);
|
|
760
|
-
if (isObjectType(schemaType))
|
|
761
|
-
return createObject(schemaType);
|
|
762
|
-
if (lastType(schemaType)?.name === "document") {
|
|
763
|
-
const doc = documentTypes.get(schemaType.name);
|
|
764
|
-
return doc === void 0 ? { type: "unknown" } : { type: "object", attributes: doc?.attributes };
|
|
765
|
-
}
|
|
766
|
-
throw new Error(`Type "${schemaType.name}" not found`);
|
|
767
|
-
}
|
|
768
|
-
function createObject(schemaType) {
|
|
769
|
-
const attributes = {}, fields = gatherFields(schemaType);
|
|
770
|
-
for (const field of fields) {
|
|
771
|
-
const fieldIsRequired = isFieldRequired(field), value = convertSchemaType(field.type);
|
|
772
|
-
if (value === null)
|
|
773
|
-
continue;
|
|
774
|
-
hasAssetRequired(field) && value.type === "object" && (value.attributes.asset.optional = !1);
|
|
775
|
-
const optional = extractOptions.enforceRequiredFields ? fieldIsRequired === !1 : !0;
|
|
776
|
-
attributes[field.name] = {
|
|
777
|
-
type: "objectAttribute",
|
|
778
|
-
value,
|
|
779
|
-
optional
|
|
780
|
-
};
|
|
781
|
-
}
|
|
782
|
-
return Object.keys(attributes).length === 0 ? { type: "unknown" } : (schemaType.type?.name !== "document" && schemaType.name !== "object" && (attributes._type = {
|
|
783
|
-
type: "objectAttribute",
|
|
784
|
-
value: {
|
|
785
|
-
type: "string",
|
|
786
|
-
value: schemaType.name
|
|
787
|
-
}
|
|
788
|
-
}), {
|
|
789
|
-
type: "object",
|
|
790
|
-
attributes
|
|
791
|
-
});
|
|
792
|
-
}
|
|
793
|
-
function createArray(arraySchemaType) {
|
|
794
|
-
const of = [];
|
|
795
|
-
for (const item of arraySchemaType.of) {
|
|
796
|
-
const field = convertSchemaType(item);
|
|
797
|
-
field.type === "inline" ? of.push({
|
|
798
|
-
type: "object",
|
|
799
|
-
attributes: {
|
|
800
|
-
_key: createKeyField()
|
|
801
|
-
},
|
|
802
|
-
rest: field
|
|
803
|
-
}) : (field.type === "object" && (field.rest = {
|
|
804
|
-
type: "object",
|
|
805
|
-
attributes: {
|
|
806
|
-
_key: createKeyField()
|
|
807
|
-
}
|
|
808
|
-
}), of.push(field));
|
|
809
|
-
}
|
|
810
|
-
return of.length === 0 ? { type: "null" } : {
|
|
811
|
-
type: "array",
|
|
812
|
-
of: of.length > 1 ? {
|
|
813
|
-
type: "union",
|
|
814
|
-
of
|
|
815
|
-
} : of[0]
|
|
816
|
-
};
|
|
817
|
-
}
|
|
818
|
-
return schema;
|
|
819
|
-
}
|
|
820
|
-
function createKeyField() {
|
|
821
|
-
return {
|
|
822
|
-
type: "objectAttribute",
|
|
823
|
-
value: {
|
|
824
|
-
type: "string"
|
|
825
|
-
}
|
|
826
|
-
};
|
|
827
|
-
}
|
|
828
|
-
function isFieldRequired(field) {
|
|
829
|
-
const { validation } = field.type;
|
|
830
|
-
if (!validation)
|
|
831
|
-
return !1;
|
|
832
|
-
const rules = Array.isArray(validation) ? validation : [validation];
|
|
833
|
-
for (const rule of rules) {
|
|
834
|
-
let required = !1;
|
|
835
|
-
const proxy = new Proxy(
|
|
836
|
-
{},
|
|
837
|
-
{
|
|
838
|
-
get: (target, methodName) => () => (methodName === "required" && (required = !0), proxy)
|
|
839
|
-
}
|
|
840
|
-
);
|
|
841
|
-
if (typeof rule == "function" && (rule(proxy), required) || typeof rule == "object" && rule !== null && "_required" in rule && rule._required === "required")
|
|
842
|
-
return !0;
|
|
843
|
-
}
|
|
844
|
-
return !1;
|
|
845
|
-
}
|
|
846
|
-
function hasAssetRequired(field) {
|
|
847
|
-
const { validation } = field.type;
|
|
848
|
-
if (!validation)
|
|
849
|
-
return !1;
|
|
850
|
-
const rules = Array.isArray(validation) ? validation : [validation];
|
|
851
|
-
for (const rule of rules) {
|
|
852
|
-
let assetRequired = !1;
|
|
853
|
-
const proxy = new Proxy(
|
|
854
|
-
{},
|
|
855
|
-
{
|
|
856
|
-
get: (target, methodName) => () => (methodName === "assetRequired" && (assetRequired = !0), proxy)
|
|
857
|
-
}
|
|
858
|
-
);
|
|
859
|
-
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"))
|
|
860
|
-
return !0;
|
|
861
|
-
}
|
|
862
|
-
return !1;
|
|
863
|
-
}
|
|
864
|
-
function isObjectType(typeDef) {
|
|
865
|
-
return isType(typeDef, "object") || typeDef.jsonType === "object" || "fields" in typeDef;
|
|
866
|
-
}
|
|
867
|
-
function isArrayType(typeDef) {
|
|
868
|
-
return isType(typeDef, "array");
|
|
869
|
-
}
|
|
870
|
-
function isReferenceType(typeDef) {
|
|
871
|
-
return isType(typeDef, "reference");
|
|
872
|
-
}
|
|
873
|
-
function isCrossDatasetReferenceType(typeDef) {
|
|
874
|
-
return isType(typeDef, "crossDatasetReference");
|
|
875
|
-
}
|
|
876
|
-
function isGlobalDocumentReferenceType(typeDef) {
|
|
877
|
-
return isType(typeDef, "globalDocumentReference");
|
|
878
|
-
}
|
|
879
|
-
function isStringType(typeDef) {
|
|
880
|
-
return isType(typeDef, "string");
|
|
881
|
-
}
|
|
882
|
-
function isNumberType(typeDef) {
|
|
883
|
-
return isType(typeDef, "number");
|
|
884
|
-
}
|
|
885
|
-
function createStringTypeNodeDefintion(stringSchemaType) {
|
|
886
|
-
const listOptions = stringSchemaType.options?.list;
|
|
887
|
-
return listOptions && Array.isArray(listOptions) ? {
|
|
888
|
-
type: "union",
|
|
889
|
-
of: listOptions.map((v) => ({
|
|
890
|
-
type: "string",
|
|
891
|
-
value: typeof v == "string" ? v : v.value
|
|
892
|
-
}))
|
|
893
|
-
} : {
|
|
894
|
-
type: "string"
|
|
895
|
-
};
|
|
896
|
-
}
|
|
897
|
-
function createNumberTypeNodeDefintion(numberSchemaType) {
|
|
898
|
-
const listOptions = numberSchemaType.options?.list;
|
|
899
|
-
return listOptions && Array.isArray(listOptions) ? {
|
|
900
|
-
type: "union",
|
|
901
|
-
of: listOptions.map((v) => ({
|
|
902
|
-
type: "number",
|
|
903
|
-
value: typeof v == "number" ? v : v.value
|
|
904
|
-
}))
|
|
905
|
-
} : {
|
|
906
|
-
type: "number"
|
|
907
|
-
};
|
|
908
|
-
}
|
|
909
|
-
function createReferenceTypeNodeDefintion(reference2) {
|
|
910
|
-
const references = gatherReferenceNames(reference2);
|
|
911
|
-
return references.length === 1 ? createReferenceTypeNode(references[0]) : {
|
|
912
|
-
type: "union",
|
|
913
|
-
of: references.map((name) => createReferenceTypeNode(name))
|
|
914
|
-
};
|
|
915
|
-
}
|
|
916
|
-
function gatherReferenceNames(type) {
|
|
917
|
-
const allReferences = gatherReferenceTypes(type);
|
|
918
|
-
return [...new Set(allReferences.map((ref) => ref.name))];
|
|
919
|
-
}
|
|
920
|
-
function gatherReferenceTypes(type) {
|
|
921
|
-
const refTo = "to" in type ? type.to : [];
|
|
922
|
-
return "type" in type && isReferenceType(type.type) ? [...gatherReferenceTypes(type.type), ...refTo] : refTo;
|
|
923
|
-
}
|
|
924
|
-
function gatherFields(type) {
|
|
925
|
-
return "fields" in type ? type.type ? gatherFields(type.type).concat(type.fields) : type.fields : [];
|
|
926
|
-
}
|
|
927
|
-
function isType(typeDef, typeName) {
|
|
928
|
-
let type = typeDef;
|
|
929
|
-
for (; type; ) {
|
|
930
|
-
if (type.name === typeName || type.type && type.type.name === typeName)
|
|
931
|
-
return !0;
|
|
932
|
-
type = type.type;
|
|
933
|
-
}
|
|
934
|
-
return !1;
|
|
935
|
-
}
|
|
936
|
-
function lastType(typeDef) {
|
|
937
|
-
let type = typeDef;
|
|
938
|
-
for (; type; ) {
|
|
939
|
-
if (!type.type)
|
|
940
|
-
return type;
|
|
941
|
-
type = type.type;
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
function sortByDependencies(compiledSchema) {
|
|
945
|
-
const seen = /* @__PURE__ */ new Set();
|
|
946
|
-
function walkDependencies(schemaType, dependencies) {
|
|
947
|
-
if (!seen.has(schemaType)) {
|
|
948
|
-
if (seen.add(schemaType), "fields" in schemaType)
|
|
949
|
-
for (const field of gatherFields(schemaType)) {
|
|
950
|
-
const last = lastType(field.type);
|
|
951
|
-
if (last.name === "document") {
|
|
952
|
-
dependencies.add(last);
|
|
953
|
-
continue;
|
|
954
|
-
}
|
|
955
|
-
let schemaTypeName;
|
|
956
|
-
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);
|
|
957
|
-
}
|
|
958
|
-
else if ("of" in schemaType)
|
|
959
|
-
for (const item of schemaType.of)
|
|
960
|
-
walkDependencies(item, dependencies);
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
const dependencyMap = /* @__PURE__ */ new Map();
|
|
964
|
-
compiledSchema.getTypeNames().forEach((typeName) => {
|
|
965
|
-
const schemaType = compiledSchema.get(typeName);
|
|
966
|
-
if (schemaType === void 0 || schemaType.type === null)
|
|
967
|
-
return;
|
|
968
|
-
const dependencies = /* @__PURE__ */ new Set();
|
|
969
|
-
walkDependencies(schemaType, dependencies), dependencyMap.set(schemaType, dependencies), seen.clear();
|
|
970
|
-
});
|
|
971
|
-
const typeNames = [], currentlyVisiting = /* @__PURE__ */ new Set(), visited = /* @__PURE__ */ new Set();
|
|
972
|
-
function visit(type) {
|
|
973
|
-
if (visited.has(type) || currentlyVisiting.has(type))
|
|
974
|
-
return;
|
|
975
|
-
currentlyVisiting.add(type);
|
|
976
|
-
const deps = dependencyMap.get(type);
|
|
977
|
-
deps !== void 0 && deps.forEach((dep) => visit(dep)), currentlyVisiting.delete(type), visited.add(type), typeNames.includes(type.name) || typeNames.unshift(type.name);
|
|
978
|
-
}
|
|
979
|
-
for (const [type] of dependencyMap)
|
|
980
|
-
visit(type);
|
|
981
|
-
return typeNames;
|
|
982
|
-
}
|
|
983
|
-
const HELP_IDS = {
|
|
984
|
-
TYPE_INVALID: "schema-type-invalid",
|
|
985
|
-
TYPE_IS_ESM_MODULE: "schema-type-is-esm-module",
|
|
986
|
-
TYPE_NAME_RESERVED: "schema-type-name-reserved",
|
|
987
|
-
TYPE_MISSING_NAME: "schema-type-missing-name-or-type",
|
|
988
|
-
TYPE_MISSING_TYPE: "schema-type-missing-name-or-type",
|
|
989
|
-
TYPE_TITLE_RECOMMENDED: "schema-type-title-is-recommended",
|
|
990
|
-
TYPE_TITLE_INVALID: "schema-type-title-is-recommended",
|
|
991
|
-
OBJECT_FIELDS_INVALID: "schema-object-fields-invalid",
|
|
992
|
-
OBJECT_FIELD_NOT_UNIQUE: "schema-object-fields-invalid",
|
|
993
|
-
OBJECT_FIELD_NAME_INVALID: "schema-object-fields-invalid",
|
|
994
|
-
OBJECT_FIELD_DEFINITION_INVALID_TYPE: "schema-object-fields-invalid",
|
|
995
|
-
ARRAY_PREDEFINED_CHOICES_INVALID: "schema-predefined-choices-invalid",
|
|
996
|
-
ARRAY_OF_ARRAY: "schema-array-of-array",
|
|
997
|
-
ARRAY_OF_INVALID: "schema-array-of-invalid",
|
|
998
|
-
ARRAY_OF_NOT_UNIQUE: "schema-array-of-invalid",
|
|
999
|
-
ARRAY_OF_TYPE_GLOBAL_TYPE_CONFLICT: "schema-array-of-type-global-type-conflict",
|
|
1000
|
-
ARRAY_OF_TYPE_BUILTIN_TYPE_CONFLICT: "schema-array-of-type-builtin-type-conflict",
|
|
1001
|
-
REFERENCE_TO_INVALID: "schema-reference-to-invalid",
|
|
1002
|
-
REFERENCE_TO_NOT_UNIQUE: "schema-reference-to-invalid",
|
|
1003
|
-
REFERENCE_INVALID_OPTIONS: "schema-reference-invalid-options",
|
|
1004
|
-
REFERENCE_INVALID_OPTIONS_LOCATION: "schema-reference-options-nesting",
|
|
1005
|
-
REFERENCE_INVALID_FILTER_PARAMS_COMBINATION: "schema-reference-filter-params-combination",
|
|
1006
|
-
SLUG_SLUGIFY_FN_RENAMED: "slug-slugifyfn-renamed",
|
|
1007
|
-
ASSET_METADATA_FIELD_INVALID: "asset-metadata-field-invalid",
|
|
1008
|
-
CROSS_DATASET_REFERENCE_INVALID: "cross-dataset-reference-invalid",
|
|
1009
|
-
GLOBAL_DOCUMENT_REFERENCE_INVALID: "global-document-reference-invalid",
|
|
1010
|
-
DEPRECATED_BLOCKEDITOR_KEY: "schema-deprecated-blockeditor-key",
|
|
1011
|
-
STANDALONE_BLOCK_TYPE: "schema-standalone-block-type"
|
|
1012
|
-
};
|
|
1013
|
-
function createValidationResult(severity, message, helpId) {
|
|
1014
|
-
if (helpId && !Object.keys(HELP_IDS).some((id) => HELP_IDS[id] === helpId))
|
|
1015
|
-
throw new Error(
|
|
1016
|
-
`Used the unknown helpId "${helpId}", please add it to the array in createValidationResult.js`
|
|
1017
|
-
);
|
|
1018
|
-
return {
|
|
1019
|
-
severity,
|
|
1020
|
-
message,
|
|
1021
|
-
helpId
|
|
1022
|
-
};
|
|
1023
|
-
}
|
|
1024
|
-
const error = (message, helpId) => createValidationResult("error", message, helpId), warning = (message, helpId) => createValidationResult("warning", message, helpId);
|
|
1025
|
-
function groupProblems(types) {
|
|
1026
|
-
return flatten(types.map((type) => getTypeProblems(type))).filter(
|
|
1027
|
-
(type) => type.problems.length > 0
|
|
1028
|
-
);
|
|
1029
|
-
}
|
|
1030
|
-
function createTypeWithMembersProblemsAccessor(memberPropertyName, getMembers = (type) => get(type, memberPropertyName)) {
|
|
1031
|
-
return function(type, parentPath) {
|
|
1032
|
-
const currentPath = [
|
|
1033
|
-
...parentPath,
|
|
1034
|
-
{ kind: "type", type: type.type, name: type.name }
|
|
1035
|
-
], members = getMembers(type) || [], memberProblems = Array.isArray(members) ? members.map((memberType) => {
|
|
1036
|
-
const propertySegment = {
|
|
1037
|
-
kind: "property",
|
|
1038
|
-
name: memberPropertyName
|
|
1039
|
-
}, memberPath = [...currentPath, propertySegment];
|
|
1040
|
-
return getTypeProblems(memberType, memberPath);
|
|
1041
|
-
}) : [
|
|
1042
|
-
[
|
|
1043
|
-
{
|
|
1044
|
-
path: currentPath,
|
|
1045
|
-
problems: [error(`Member declaration (${memberPropertyName}) is not an array`)]
|
|
1046
|
-
}
|
|
1047
|
-
]
|
|
1048
|
-
];
|
|
1049
|
-
return [
|
|
1050
|
-
{
|
|
1051
|
-
path: currentPath,
|
|
1052
|
-
problems: type._problems || []
|
|
1053
|
-
},
|
|
1054
|
-
...flatten(memberProblems)
|
|
1055
|
-
];
|
|
1056
|
-
};
|
|
1057
|
-
}
|
|
1058
|
-
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(
|
|
1059
|
-
"to",
|
|
1060
|
-
(type) => "to" in type ? arrify(type.to) : []
|
|
1061
|
-
), getBlockAnnotationProblems = createTypeWithMembersProblemsAccessor("marks.annotations"), getBlockMemberProblems = createTypeWithMembersProblemsAccessor("of"), getBlockProblems = (type, problems) => [
|
|
1062
|
-
...getBlockAnnotationProblems(type, problems),
|
|
1063
|
-
...getBlockMemberProblems(type, problems)
|
|
1064
|
-
];
|
|
1065
|
-
function getDefaultProblems(type, path = []) {
|
|
1066
|
-
return [
|
|
1067
|
-
{
|
|
1068
|
-
path: [...path, { kind: "type", type: type.type, name: type.name }],
|
|
1069
|
-
problems: type._problems || []
|
|
1070
|
-
}
|
|
1071
|
-
];
|
|
1072
|
-
}
|
|
1073
|
-
function getTypeProblems(type, path = []) {
|
|
1074
|
-
switch (type.type) {
|
|
1075
|
-
case "object":
|
|
1076
|
-
return getObjectProblems(type, path);
|
|
1077
|
-
case "document":
|
|
1078
|
-
return getObjectProblems(type, path);
|
|
1079
|
-
case "array":
|
|
1080
|
-
return getArrayProblems(type, path);
|
|
1081
|
-
case "reference":
|
|
1082
|
-
return getReferenceProblems(type, path);
|
|
1083
|
-
case "block":
|
|
1084
|
-
return getBlockProblems(type, path);
|
|
1085
|
-
case "image":
|
|
1086
|
-
return getImageProblems(type, path);
|
|
1087
|
-
case "file":
|
|
1088
|
-
return getFileProblems(type, path);
|
|
1089
|
-
default:
|
|
1090
|
-
return getDefaultProblems(type, path);
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
function getDupes(array2, selector = (v) => v) {
|
|
1094
|
-
const dupes = array2.reduce((acc, item) => {
|
|
1095
|
-
const key = selector(item);
|
|
1096
|
-
return acc[key] || (acc[key] = []), acc[key].push(item), acc;
|
|
1097
|
-
}, {});
|
|
1098
|
-
return Object.keys(dupes).map((key) => dupes[key].length > 1 ? dupes[key] : null).filter(Boolean);
|
|
1099
|
-
}
|
|
1100
|
-
const NOOP_VISITOR = (typeDef) => typeDef, TYPE_TYPE = { name: "type", type: null }, FUTURE_RESERVED = ["any", "time", "date"];
|
|
1101
|
-
function traverseSchema(types = [], coreTypes2 = [], visitor = NOOP_VISITOR) {
|
|
1102
|
-
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);
|
|
1103
|
-
coreTypes2.forEach((coreType) => {
|
|
1104
|
-
coreTypesRegistry[coreType.name] = coreType;
|
|
1105
|
-
}), types.forEach((type, i) => {
|
|
1106
|
-
registry[type && type.name || `__unnamed_${i}`] = {};
|
|
1107
|
-
});
|
|
1108
|
-
function getType(typeName) {
|
|
1109
|
-
return typeName === "type" ? TYPE_TYPE : coreTypesRegistry[typeName] || registry[typeName] || null;
|
|
1110
|
-
}
|
|
1111
|
-
const duplicateNames = uniq(flatten(getDupes(typeNames)));
|
|
1112
|
-
function isDuplicate(typeName) {
|
|
1113
|
-
return duplicateNames.includes(typeName);
|
|
1114
|
-
}
|
|
1115
|
-
function getTypeNames() {
|
|
1116
|
-
return typeNames.concat(coreTypeNames2);
|
|
1117
|
-
}
|
|
1118
|
-
function isReserved(typeName) {
|
|
1119
|
-
return typeName === "type" || reservedTypeNames.includes(typeName);
|
|
1120
|
-
}
|
|
1121
|
-
const visitType = (isRoot) => (typeDef, index) => visitor(typeDef, {
|
|
1122
|
-
visit: visitType(!1),
|
|
1123
|
-
isRoot,
|
|
1124
|
-
getType,
|
|
1125
|
-
getTypeNames,
|
|
1126
|
-
isReserved,
|
|
1127
|
-
isDuplicate,
|
|
1128
|
-
index
|
|
1129
|
-
});
|
|
1130
|
-
return coreTypes2.forEach((coreTypeDef) => {
|
|
1131
|
-
Object.assign(coreTypesRegistry[coreTypeDef.name], visitType(coreTypeDef));
|
|
1132
|
-
}), types.forEach((typeDef, i) => {
|
|
1133
|
-
Object.assign(
|
|
1134
|
-
registry[typeDef && typeDef.name || `__unnamed_${i}`],
|
|
1135
|
-
visitType(!0)(typeDef, i)
|
|
1136
|
-
);
|
|
1137
|
-
}), {
|
|
1138
|
-
get(typeName) {
|
|
1139
|
-
const res = registry[typeName] || coreTypesRegistry[typeName];
|
|
1140
|
-
if (res)
|
|
1141
|
-
return res;
|
|
1142
|
-
throw new Error(`No such type: ${typeName}`);
|
|
1143
|
-
},
|
|
1144
|
-
has(typeName) {
|
|
1145
|
-
return typeName in registry || typeName in coreTypesRegistry;
|
|
1146
|
-
},
|
|
1147
|
-
getTypeNames() {
|
|
1148
|
-
return Object.keys(registry);
|
|
1149
|
-
},
|
|
1150
|
-
getTypes() {
|
|
1151
|
-
return this.getTypeNames().map(this.get);
|
|
1152
|
-
},
|
|
1153
|
-
toJSON() {
|
|
1154
|
-
return this.getTypes();
|
|
1155
|
-
}
|
|
1156
|
-
};
|
|
1157
|
-
}
|
|
1158
|
-
const coreTypes = [
|
|
1159
|
-
{ name: "array", jsonType: "array", type: "type" },
|
|
1160
|
-
{ name: "block", jsonType: "object", type: "type" },
|
|
1161
|
-
{ name: "boolean", jsonType: "boolean", type: "type" },
|
|
1162
|
-
{ name: "datetime", jsonType: "string", type: "type" },
|
|
1163
|
-
{ name: "date", jsonType: "string", type: "type" },
|
|
1164
|
-
{ name: "document", jsonType: "object", type: "type" },
|
|
1165
|
-
{ name: "email", jsonType: "string", type: "type" },
|
|
1166
|
-
{ name: "file", jsonType: "object", type: "type" },
|
|
1167
|
-
{ name: "geopoint", jsonType: "object", type: "type" },
|
|
1168
|
-
{ name: "image", jsonType: "object", type: "type" },
|
|
1169
|
-
{ name: "number", jsonType: "number", type: "type" },
|
|
1170
|
-
{ name: "object", jsonType: "object", type: "type" },
|
|
1171
|
-
{ name: "reference", jsonType: "object", type: "type" },
|
|
1172
|
-
{ name: "crossDatasetReference", jsonType: "object", type: "type" },
|
|
1173
|
-
{ name: "globalDocumentReference", jsonType: "object", type: "type" },
|
|
1174
|
-
{ name: "slug", jsonType: "object", type: "type" },
|
|
1175
|
-
{ name: "span", jsonType: "object", type: "type" },
|
|
1176
|
-
{ name: "string", jsonType: "string", type: "type" },
|
|
1177
|
-
{ name: "telephone", jsonType: "string", type: "type" },
|
|
1178
|
-
{ name: "text", jsonType: "string", type: "type" },
|
|
1179
|
-
{ name: "url", jsonType: "string", type: "type" }
|
|
1180
|
-
], coreTypeNames = coreTypes.map((t) => t.name);
|
|
1181
|
-
function traverseSanitySchema(schemaTypes, visitor) {
|
|
1182
|
-
return traverseSchema(schemaTypes, coreTypes, visitor);
|
|
1183
|
-
}
|
|
1184
|
-
function isPrimitiveTypeName(typeName) {
|
|
1185
|
-
return typeName === "string" || typeName === "number" || typeName === "boolean";
|
|
1186
|
-
}
|
|
1187
|
-
function isAssignable(typeName, type) {
|
|
1188
|
-
return (typeof type.name == "string" ? type.name : type.type) === typeName;
|
|
1189
|
-
}
|
|
1190
|
-
function quote$2(n) {
|
|
1191
|
-
return `"${n}"`;
|
|
1192
|
-
}
|
|
1193
|
-
function pluralize(arr, suf = "s") {
|
|
1194
|
-
return arr.length === 1 ? "" : suf;
|
|
1195
|
-
}
|
|
1196
|
-
function format(value) {
|
|
1197
|
-
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);
|
|
1198
|
-
}
|
|
1199
|
-
var array = (typeDef, visitorContext) => {
|
|
1200
|
-
const ofIsArray = Array.isArray(typeDef.of);
|
|
1201
|
-
if (ofIsArray) {
|
|
1202
|
-
const invalid = typeDef.of.reduce((errs, def, idx) => {
|
|
1203
|
-
if (typeof def.name == "string" && // specifying the same name as the type is redundant, but should not be a hard error at this point
|
|
1204
|
-
// Consider showing a warning for this and deprecate this ability eventually
|
|
1205
|
-
def.name !== def.type && coreTypeNames.includes(def.name))
|
|
1206
|
-
return errs.concat(
|
|
1207
|
-
error(
|
|
1208
|
-
`Found array member declaration with the same type name as a built-in type ("${def.name}"). Array members can not be given the same name as a built-in type.`,
|
|
1209
|
-
HELP_IDS.ARRAY_OF_TYPE_BUILTIN_TYPE_CONFLICT
|
|
1210
|
-
)
|
|
1211
|
-
);
|
|
1212
|
-
if (def.type === "object" && def.name && visitorContext.getType(def.name))
|
|
1213
|
-
return errs.concat(
|
|
1214
|
-
warning(
|
|
1215
|
-
`Found array member declaration with the same name as the global schema type "${def.name}". It's recommended to use a unique name to avoid possibly incompatible data types that shares the same name.`,
|
|
1216
|
-
HELP_IDS.ARRAY_OF_TYPE_GLOBAL_TYPE_CONFLICT
|
|
1217
|
-
)
|
|
1218
|
-
);
|
|
1219
|
-
if (def.type === "array")
|
|
1220
|
-
return errs.concat(
|
|
1221
|
-
error(
|
|
1222
|
-
'Found array member declaration of type "array" - multidimensional arrays are not currently supported by Sanity',
|
|
1223
|
-
HELP_IDS.ARRAY_OF_ARRAY
|
|
1224
|
-
)
|
|
1225
|
-
);
|
|
1226
|
-
if (def)
|
|
1227
|
-
return errs;
|
|
1228
|
-
const err = `Found ${def === null ? "null" : typeof def}, expected member declaration`;
|
|
1229
|
-
return errs.concat(
|
|
1230
|
-
error(
|
|
1231
|
-
`Found invalid type member declaration in array at index ${idx}: ${err}`,
|
|
1232
|
-
HELP_IDS.ARRAY_OF_INVALID
|
|
1233
|
-
)
|
|
1234
|
-
);
|
|
1235
|
-
}, []);
|
|
1236
|
-
if (invalid.length > 0)
|
|
1237
|
-
return {
|
|
1238
|
-
...typeDef,
|
|
1239
|
-
of: [],
|
|
1240
|
-
_problems: invalid
|
|
1241
|
-
};
|
|
1242
|
-
}
|
|
1243
|
-
const problems = flatten([
|
|
1244
|
-
ofIsArray ? getDupes(typeDef.of, (t) => `${t.name};${t.type}`).map(
|
|
1245
|
-
(dupes) => error(
|
|
1246
|
-
`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`,
|
|
1247
|
-
HELP_IDS.ARRAY_OF_NOT_UNIQUE
|
|
1248
|
-
)
|
|
1249
|
-
) : error(
|
|
1250
|
-
'The array type is missing or having an invalid value for the required "of" property',
|
|
1251
|
-
HELP_IDS.ARRAY_OF_INVALID
|
|
1252
|
-
)
|
|
1253
|
-
]), of = ofIsArray ? typeDef.of : [], hasObjectTypesWithoutName = of.some(
|
|
1254
|
-
(type) => type.type === "object" && typeof type.name > "u"
|
|
1255
|
-
);
|
|
1256
|
-
of.some((ofType) => ofType.type === "block") && hasObjectTypesWithoutName && problems.push(
|
|
1257
|
-
error(
|
|
1258
|
-
"The array type's 'of' property can't have an object type without a 'name' property as member, when the 'block' type is also a member of that array.",
|
|
1259
|
-
HELP_IDS.ARRAY_OF_INVALID
|
|
1260
|
-
)
|
|
1261
|
-
);
|
|
1262
|
-
const [primitiveTypes, objectTypes] = partition(
|
|
1263
|
-
of,
|
|
1264
|
-
(ofType) => isPrimitiveTypeName(ofType.type) || isPrimitiveTypeName(visitorContext.getType(ofType.type)?.jsonType)
|
|
1265
|
-
), isMixedArray = primitiveTypes.length > 0 && objectTypes.length > 0;
|
|
1266
|
-
if (isMixedArray) {
|
|
1267
|
-
const primitiveTypeNames = primitiveTypes.map((t) => t.type), objectTypeNames = objectTypes.map((t) => t.type);
|
|
1268
|
-
problems.push(
|
|
1269
|
-
error(
|
|
1270
|
-
`The array type's 'of' property can't have both object types and primitive types (found primitive type ${pluralize(
|
|
1271
|
-
primitiveTypeNames
|
|
1272
|
-
)} ${humanizeList(primitiveTypeNames.map(quote$2))} and object type${pluralize(
|
|
1273
|
-
objectTypeNames
|
|
1274
|
-
)} ${humanizeList(objectTypeNames.map(quote$2))})`,
|
|
1275
|
-
HELP_IDS.ARRAY_OF_INVALID
|
|
1276
|
-
)
|
|
1277
|
-
);
|
|
1278
|
-
}
|
|
1279
|
-
const list = typeDef?.options?.list;
|
|
1280
|
-
return !isMixedArray && Array.isArray(list) && (primitiveTypes.length > 0 ? list.forEach((option) => {
|
|
1281
|
-
const value = option?.value ?? option;
|
|
1282
|
-
if (!primitiveTypes.some((primitiveType) => typeof value === visitorContext.getType(primitiveType.type).jsonType)) {
|
|
1283
|
-
const formattedTypeList = humanizeList(
|
|
1284
|
-
primitiveTypes.map((t) => t.name || t.type),
|
|
1285
|
-
{ conjunction: "or" }
|
|
1286
|
-
);
|
|
1287
|
-
problems.push(
|
|
1288
|
-
error(
|
|
1289
|
-
`An invalid entry found in options.list: ${format(
|
|
1290
|
-
value
|
|
1291
|
-
)}. Must be either a value of type ${formattedTypeList}, or an object with {title: string, value: ${formattedTypeList}}`,
|
|
1292
|
-
HELP_IDS.ARRAY_PREDEFINED_CHOICES_INVALID
|
|
1293
|
-
)
|
|
1294
|
-
);
|
|
1295
|
-
}
|
|
1296
|
-
}) : list.forEach((option) => {
|
|
1297
|
-
const optionTypeName = option._type || "object";
|
|
1298
|
-
objectTypes.some(
|
|
1299
|
-
(validObjectType) => isAssignable(optionTypeName, validObjectType)
|
|
1300
|
-
) || problems.push(
|
|
1301
|
-
error(
|
|
1302
|
-
`An invalid entry found in options.list: ${format(
|
|
1303
|
-
option
|
|
1304
|
-
)}. Must be an object with "_type" set to ${humanizeList(
|
|
1305
|
-
objectTypes.map((t) => t.name || t.type).map((t) => t === "object" ? "undefined" : quote$2(t)),
|
|
1306
|
-
{ conjunction: "or" }
|
|
1307
|
-
)}`,
|
|
1308
|
-
HELP_IDS.ARRAY_PREDEFINED_CHOICES_INVALID
|
|
1309
|
-
)
|
|
1310
|
-
);
|
|
1311
|
-
})), typeDef?.options?.list && typeDef?.options?.layout === "tags" && problems.push(
|
|
1312
|
-
warning(
|
|
1313
|
-
"Found array member declaration with both tags layout and a list of predefined values. If you want to display a list of predefined values, remove the tags layout from `options`."
|
|
1314
|
-
)
|
|
1315
|
-
), {
|
|
1316
|
-
...typeDef,
|
|
1317
|
-
of: of.map(visitorContext.visit),
|
|
1318
|
-
_problems: problems
|
|
1319
|
-
};
|
|
1320
|
-
};
|
|
1321
|
-
function isJSONTypeOf(type, jsonType, visitorContext) {
|
|
1322
|
-
if ("jsonType" in type)
|
|
1323
|
-
return type.jsonType === jsonType;
|
|
1324
|
-
const parentType = visitorContext.getType(type.type);
|
|
1325
|
-
if (!parentType)
|
|
1326
|
-
throw new Error(`Could not resolve jsonType of ${type.name}. No parent type found`);
|
|
1327
|
-
return isJSONTypeOf(parentType, jsonType, visitorContext);
|
|
1328
|
-
}
|
|
1329
|
-
const getTypeOf = (thing) => Array.isArray(thing) ? "array" : typeof thing, quote$1 = (str) => `"${str}"`, allowedKeys = [
|
|
1330
|
-
"components",
|
|
1331
|
-
"lists",
|
|
1332
|
-
"marks",
|
|
1333
|
-
"name",
|
|
1334
|
-
"of",
|
|
1335
|
-
"options",
|
|
1336
|
-
"styles",
|
|
1337
|
-
"title",
|
|
1338
|
-
"type",
|
|
1339
|
-
"validation"
|
|
1340
|
-
], allowedMarkKeys = ["decorators", "annotations"], allowedStyleKeys = ["blockEditor", "title", "value", "icon", "component"], allowedDecoratorKeys = ["blockEditor", "title", "value", "icon", "component"], allowedListKeys = ["title", "value", "icon", "component"], supportedBuiltInObjectTypes = [
|
|
1341
|
-
"file",
|
|
1342
|
-
"image",
|
|
1343
|
-
"object",
|
|
1344
|
-
"reference",
|
|
1345
|
-
"crossDatasetReference",
|
|
1346
|
-
"globalDocumentReference"
|
|
1347
|
-
];
|
|
1348
|
-
function validateBlockType(typeDef, visitorContext) {
|
|
1349
|
-
const problems = [];
|
|
1350
|
-
let styles = typeDef.styles, lists = typeDef.lists, marks = typeDef.marks, members = typeDef.of;
|
|
1351
|
-
const disallowedKeys = Object.keys(typeDef).filter(
|
|
1352
|
-
(key) => !allowedKeys.includes(key) && !key.startsWith("_")
|
|
1353
|
-
);
|
|
1354
|
-
return disallowedKeys.length > 0 && problems.push(
|
|
1355
|
-
error(
|
|
1356
|
-
`Found unknown properties for block declaration: ${humanizeList(
|
|
1357
|
-
disallowedKeys.map(quote$1)
|
|
1358
|
-
)}`
|
|
1359
|
-
)
|
|
1360
|
-
), 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)), {
|
|
1361
|
-
...omit(typeDef, disallowedKeys),
|
|
1362
|
-
marks,
|
|
1363
|
-
styles,
|
|
1364
|
-
name: typeDef.name || typeDef.type,
|
|
1365
|
-
of: members,
|
|
1366
|
-
_problems: problems
|
|
1367
|
-
};
|
|
1368
|
-
}
|
|
1369
|
-
function validateMarks(marks, visitorContext, problems) {
|
|
1370
|
-
let decorators = marks.decorators, annotations = marks.annotations;
|
|
1371
|
-
if (!isPlainObject(marks))
|
|
1372
|
-
return problems.push(error(`"marks" declaration should be an object, got ${getTypeOf(marks)}`)), problems;
|
|
1373
|
-
const disallowedMarkKeys = Object.keys(marks).filter(
|
|
1374
|
-
(key) => !allowedMarkKeys.includes(key) && !key.startsWith("_")
|
|
1375
|
-
);
|
|
1376
|
-
return disallowedMarkKeys.length > 0 && problems.push(
|
|
1377
|
-
error(
|
|
1378
|
-
`Found unknown properties for block declaration: ${humanizeList(
|
|
1379
|
-
disallowedMarkKeys.map(quote$1)
|
|
1380
|
-
)}`
|
|
1381
|
-
)
|
|
1382
|
-
), decorators && !Array.isArray(decorators) ? problems.push(
|
|
1383
|
-
error(`"marks.decorators" declaration should be an array, got ${getTypeOf(decorators)}`)
|
|
1384
|
-
) : decorators && (decorators.filter((dec) => !!dec.blockEditor).forEach((dec) => {
|
|
1385
|
-
dec.icon = dec.blockEditor.icon, dec.component = dec.blockEditor.render;
|
|
1386
|
-
}), decorators = validateDecorators(decorators, visitorContext, problems)), annotations && !Array.isArray(annotations) ? problems.push(
|
|
1387
|
-
error(`"marks.annotations" declaration should be an array, got ${getTypeOf(annotations)}`)
|
|
1388
|
-
) : annotations && (annotations = validateAnnotations(annotations, visitorContext, problems)), { ...marks, decorators, annotations };
|
|
1389
|
-
}
|
|
1390
|
-
function validateLists(lists, visitorContext, problems) {
|
|
1391
|
-
return Array.isArray(lists) ? (lists.forEach((list, index) => {
|
|
1392
|
-
if (!isPlainObject(list)) {
|
|
1393
|
-
problems.push(error(`List must be an object, got ${getTypeOf(list)}`));
|
|
1394
|
-
return;
|
|
1395
|
-
}
|
|
1396
|
-
const name = list.value || `#${index}`, disallowedKeys = Object.keys(list).filter(
|
|
1397
|
-
(key) => !allowedListKeys.includes(key) && !key.startsWith("_")
|
|
1398
|
-
);
|
|
1399
|
-
disallowedKeys.length > 0 && problems.push(
|
|
1400
|
-
error(
|
|
1401
|
-
`Found unknown properties for list ${name}: ${humanizeList(disallowedKeys.map(quote$1))}`
|
|
1402
|
-
)
|
|
1403
|
-
), list.value ? typeof list.value != "string" ? problems.push(
|
|
1404
|
-
error(
|
|
1405
|
-
`List type #${index} has an invalid "value" property, expected string, got ${getTypeOf(
|
|
1406
|
-
list.value
|
|
1407
|
-
)}`
|
|
1408
|
-
)
|
|
1409
|
-
) : list.title || problems.push(warning(`List type ${name} is missing recommended "title" property`)) : problems.push(error(`List #${index} is missing required "value" property`));
|
|
1410
|
-
}), lists) : (problems.push(error(`"lists" declaration should be an array, got ${getTypeOf(lists)}`)), problems);
|
|
1411
|
-
}
|
|
1412
|
-
function validateStyles(styles, visitorContext, problems) {
|
|
1413
|
-
return Array.isArray(styles) ? (styles.forEach((style, index) => {
|
|
1414
|
-
if (!isPlainObject(style)) {
|
|
1415
|
-
problems.push(error(`Style must be an object, got ${getTypeOf(style)}`));
|
|
1416
|
-
return;
|
|
1417
|
-
}
|
|
1418
|
-
const name = style.value || `#${index}`, disallowedKeys = Object.keys(style).filter(
|
|
1419
|
-
(key) => !allowedStyleKeys.includes(key) && !key.startsWith("_")
|
|
1420
|
-
);
|
|
1421
|
-
disallowedKeys.length > 0 && problems.push(
|
|
1422
|
-
error(
|
|
1423
|
-
`Found unknown properties for style ${name}: ${humanizeList(disallowedKeys.map(quote$1))}`
|
|
1424
|
-
)
|
|
1425
|
-
), style.value ? typeof style.value != "string" ? problems.push(
|
|
1426
|
-
error(
|
|
1427
|
-
`Style #${index} has an invalid "value" property, expected string, got ${getTypeOf(
|
|
1428
|
-
style.value
|
|
1429
|
-
)}`
|
|
1430
|
-
)
|
|
1431
|
-
) : style.title || problems.push(warning(`Style ${name} is missing recommended "title" property`)) : problems.push(error(`Style #${index} is missing required "value" property`)), typeof style.blockEditor < "u" && (problems.push(
|
|
1432
|
-
warning(
|
|
1433
|
-
'Style has deprecated key "blockEditor", please refer to the documentation on how to configure the block type for version 3.',
|
|
1434
|
-
HELP_IDS.DEPRECATED_BLOCKEDITOR_KEY
|
|
1435
|
-
)
|
|
1436
|
-
), style.component = style.component || style.blockEditor.render);
|
|
1437
|
-
}), styles) : (problems.push(error(`"styles" declaration should be an array, got ${getTypeOf(styles)}`)), problems);
|
|
1438
|
-
}
|
|
1439
|
-
function validateDecorators(decorators, visitorContext, problems) {
|
|
1440
|
-
return decorators.forEach((decorator, index) => {
|
|
1441
|
-
if (!isPlainObject(decorator)) {
|
|
1442
|
-
problems.push(error(`Annotation must be an object, got ${getTypeOf(decorator)}`));
|
|
1443
|
-
return;
|
|
1444
|
-
}
|
|
1445
|
-
const name = decorator.value || `#${index}`, disallowedKeys = Object.keys(decorator).filter(
|
|
1446
|
-
(key) => !allowedDecoratorKeys.includes(key) && !key.startsWith("_")
|
|
1447
|
-
);
|
|
1448
|
-
disallowedKeys.length > 0 && problems.push(
|
|
1449
|
-
error(
|
|
1450
|
-
`Found unknown properties for decorator ${name}: ${humanizeList(
|
|
1451
|
-
disallowedKeys.map(quote$1)
|
|
1452
|
-
)}`
|
|
1453
|
-
)
|
|
1454
|
-
), decorator.value ? typeof decorator.value != "string" ? problems.push(
|
|
1455
|
-
error(
|
|
1456
|
-
`Decorator #${index} has an invalid "value" property, expected string, got ${getTypeOf(
|
|
1457
|
-
decorator.value
|
|
1458
|
-
)}`
|
|
1459
|
-
)
|
|
1460
|
-
) : decorator.title || problems.push(warning(`Decorator ${name} is missing recommended "title" property`)) : problems.push(error(`Decorator #${index} is missing required "value" property`)), typeof decorator.blockEditor < "u" && (problems.push(
|
|
1461
|
-
warning(
|
|
1462
|
-
`Decorator "${name}" has deprecated key "blockEditor", please refer to the documentation on how to configure the block type for version 3.`,
|
|
1463
|
-
HELP_IDS.DEPRECATED_BLOCKEDITOR_KEY
|
|
1464
|
-
)
|
|
1465
|
-
), decorator.icon = decorator.icon || decorator.blockEditor.icon, decorator.component = decorator.component || decorator.blockEditor.render);
|
|
1466
|
-
}), decorators;
|
|
1467
|
-
}
|
|
1468
|
-
function validateAnnotations(annotations, visitorContext, problems) {
|
|
1469
|
-
return annotations.map((annotation) => {
|
|
1470
|
-
if (!isPlainObject(annotation))
|
|
1471
|
-
return {
|
|
1472
|
-
...annotation,
|
|
1473
|
-
_problems: [error(`Annotation must be an object, got ${getTypeOf(annotation)}`)]
|
|
1474
|
-
};
|
|
1475
|
-
const { _problems } = visitorContext.visit(annotation, visitorContext), targetType = annotation.type && visitorContext.getType(annotation.type);
|
|
1476
|
-
return targetType && !isJSONTypeOf(targetType, "object", visitorContext) && _problems.push(
|
|
1477
|
-
error(
|
|
1478
|
-
`Annotation cannot have type "${annotation.type}" - annotation types must inherit from object`
|
|
1479
|
-
)
|
|
1480
|
-
), typeof annotation.blockEditor < "u" && (problems.push(
|
|
1481
|
-
warning(
|
|
1482
|
-
'Annotation has deprecated key "blockEditor", please refer to the documentation on how to configure the block type for version 3.',
|
|
1483
|
-
HELP_IDS.DEPRECATED_BLOCKEDITOR_KEY
|
|
1484
|
-
)
|
|
1485
|
-
), annotation.icon = annotation.icon || annotation.blockEditor.icon, annotation.blockEditor?.render && !annotation.components?.annotation && (annotation.components = annotation.components || {}, annotation.components.annotation = annotation.components.annotation || annotation.blockEditor.render)), { ...annotation, _problems };
|
|
1486
|
-
});
|
|
1487
|
-
}
|
|
1488
|
-
function validateMembers(members, visitorContext, problems) {
|
|
1489
|
-
if (!Array.isArray(members)) {
|
|
1490
|
-
problems.push(error(`"of" declaration should be an array, got ${getTypeOf(members)}`));
|
|
1491
|
-
return;
|
|
1492
|
-
}
|
|
1493
|
-
return members.map((member) => {
|
|
1494
|
-
const { _problems } = visitorContext.visit(member, visitorContext);
|
|
1495
|
-
if (member.type === "object" && member.name && visitorContext.getType(member.name))
|
|
1496
|
-
return {
|
|
1497
|
-
...member,
|
|
1498
|
-
_problems: [
|
|
1499
|
-
warning(
|
|
1500
|
-
`Found array member declaration with the same name as the global schema type "${member.name}". It's recommended to use a unique name to avoid possibly incompatible data types that shares the same name.`,
|
|
1501
|
-
HELP_IDS.ARRAY_OF_TYPE_GLOBAL_TYPE_CONFLICT
|
|
1502
|
-
)
|
|
1503
|
-
]
|
|
1504
|
-
};
|
|
1505
|
-
let type = member;
|
|
1506
|
-
for (; type && !type.jsonType; )
|
|
1507
|
-
type = visitorContext.getType(type.type);
|
|
1508
|
-
const nonObjectCoreTypes = coreTypeNames.filter((n) => !supportedBuiltInObjectTypes.includes(n));
|
|
1509
|
-
return (
|
|
1510
|
-
// Must be object-like type (to validate hoisted types)
|
|
1511
|
-
type && type.jsonType !== "object" || // Can't be a core type, or core object type that isn't supported (like 'span')
|
|
1512
|
-
nonObjectCoreTypes.some((coreName) => coreName === member.type) ? {
|
|
1513
|
-
...member,
|
|
1514
|
-
_problems: [
|
|
1515
|
-
error(
|
|
1516
|
-
`Block member types must be a supported object-like type. The following built-in types are supported: '${supportedBuiltInObjectTypes.join(
|
|
1517
|
-
"', '"
|
|
1518
|
-
)}'. You can also use shorthands for previously defined object types like {type: 'myObjectType'}`,
|
|
1519
|
-
HELP_IDS.ARRAY_OF_TYPE_BUILTIN_TYPE_CONFLICT
|
|
1520
|
-
)
|
|
1521
|
-
]
|
|
1522
|
-
} : { ...member, _problems }
|
|
1523
|
-
);
|
|
1524
|
-
});
|
|
1525
|
-
}
|
|
1526
|
-
function validateNonObjectFieldsProp(typeDef, visitorContext) {
|
|
1527
|
-
if (!("fields" in typeDef))
|
|
1528
|
-
return [];
|
|
1529
|
-
let type = typeDef;
|
|
1530
|
-
for (; type && !type.jsonType; )
|
|
1531
|
-
type = visitorContext.getType(type.type);
|
|
1532
|
-
return type && type.jsonType !== "object" ? [error('Type has propery "fields", but is not an object/document type.')] : [];
|
|
1533
|
-
}
|
|
1534
|
-
const quote = (str) => `"${str}"`;
|
|
1535
|
-
function validateTypeName(typeName, visitorContext) {
|
|
1536
|
-
const possibleTypeNames = visitorContext.getTypeNames();
|
|
1537
|
-
if (!typeName)
|
|
1538
|
-
return [error("Type is missing a type.", HELP_IDS.TYPE_MISSING_TYPE)];
|
|
1539
|
-
if (typeof typeName != "string")
|
|
1540
|
-
return [
|
|
1541
|
-
error(
|
|
1542
|
-
'Type has an invalid "type"-property - should be a string.',
|
|
1543
|
-
HELP_IDS.TYPE_MISSING_TYPE
|
|
1544
|
-
)
|
|
1545
|
-
];
|
|
1546
|
-
if (!possibleTypeNames.includes(typeName)) {
|
|
1547
|
-
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" })}?` : "";
|
|
1548
|
-
return [error(`Unknown type: ${typeName}.${suggestion}`)];
|
|
1549
|
-
}
|
|
1550
|
-
return [];
|
|
1551
|
-
}
|
|
1552
|
-
function validateDeprecatedProperties(type) {
|
|
1553
|
-
const warnings = [];
|
|
1554
|
-
return type?.inputComponent && warnings.push(
|
|
1555
|
-
warning('The "inputComponent" property is deprecated. Use "components.input" instead.')
|
|
1556
|
-
), type?.preview?.component && warnings.push(
|
|
1557
|
-
warning('The "preview.component" property is deprecated. Use "components.preview" instead.')
|
|
1558
|
-
), type?.diffComponent && warnings.push(
|
|
1559
|
-
warning('The "diffComponent" property is deprecated. Use "components.diff" instead.')
|
|
1560
|
-
), type?.options?.editModal && warnings.push(
|
|
1561
|
-
warning('The "options.editModal" property is deprecated. Use "options.modal" instead.')
|
|
1562
|
-
), type?.options?.isHighlighted && warnings.push(
|
|
1563
|
-
warning(
|
|
1564
|
-
'The "options.isHighlighted" property is deprecated. You can put fields behind a collapsed fieldset if you want to hide them from plain sight.'
|
|
1565
|
-
)
|
|
1566
|
-
), warnings;
|
|
1567
|
-
}
|
|
1568
|
-
var common = (typeDef, visitorContext) => ({
|
|
1569
|
-
...typeDef,
|
|
1570
|
-
_problems: [
|
|
1571
|
-
...validateTypeName(typeDef.type, visitorContext),
|
|
1572
|
-
...validateNonObjectFieldsProp(typeDef, visitorContext),
|
|
1573
|
-
...validateDeprecatedProperties(typeDef)
|
|
1574
|
-
].filter(Boolean)
|
|
1575
|
-
});
|
|
1576
|
-
function normalizeToProp$2(typeDef) {
|
|
1577
|
-
return Array.isArray(typeDef.to) ? typeDef.to : typeDef.to ? [typeDef.to] : typeDef.to;
|
|
1578
|
-
}
|
|
1579
|
-
const VALID_DATASET = /^[a-z0-9~][-_a-z0-9]+$/;
|
|
1580
|
-
function isValidDatasetName(name) {
|
|
1581
|
-
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`;
|
|
1582
|
-
}
|
|
1583
|
-
var crossDatasetReference = (typeDef, visitorContext) => {
|
|
1584
|
-
const isValidTo = Array.isArray(typeDef.to) || isPlainObject(typeDef.to), normalizedTo = normalizeToProp$2(typeDef), problems = flatten([
|
|
1585
|
-
isValidTo ? getDupes(normalizedTo, (t) => `${t.name};${t.type}`).map(
|
|
1586
|
-
(dupes) => error(
|
|
1587
|
-
`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`,
|
|
1588
|
-
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
1589
|
-
)
|
|
1590
|
-
) : error(
|
|
1591
|
-
'The cross dataset reference type is missing or having an invalid value for the required "to" property. It should be an array of accepted types.',
|
|
1592
|
-
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
1593
|
-
)
|
|
1594
|
-
]);
|
|
1595
|
-
if (isValidTo && normalizedTo.length === 0 && problems.push(
|
|
1596
|
-
error(
|
|
1597
|
-
'The cross dataset reference type should define at least one referenced type. Please check the "to" property.',
|
|
1598
|
-
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
1599
|
-
)
|
|
1600
|
-
), normalizedTo.forEach((crossDatasetTypeDef, index) => {
|
|
1601
|
-
crossDatasetTypeDef.type || problems.push(
|
|
1602
|
-
error(
|
|
1603
|
-
`The referenced type at index ${index} must be named. Specify the name of the type you want to create references to.`,
|
|
1604
|
-
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
1605
|
-
)
|
|
1606
|
-
), isPlainObject(crossDatasetTypeDef.preview) || problems.push(
|
|
1607
|
-
error(
|
|
1608
|
-
`Missing required preview config for the referenced type "${crossDatasetTypeDef.type || "<unknown type>"}"`,
|
|
1609
|
-
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
1610
|
-
)
|
|
1611
|
-
);
|
|
1612
|
-
}), typeof typeDef.dataset == "string") {
|
|
1613
|
-
const datasetValidation = isValidDatasetName(typeDef.dataset);
|
|
1614
|
-
datasetValidation !== !0 && problems.push(error(datasetValidation, HELP_IDS.CROSS_DATASET_REFERENCE_INVALID));
|
|
1615
|
-
} else
|
|
1616
|
-
problems.push(
|
|
1617
|
-
error(
|
|
1618
|
-
"A cross dataset reference must specify a `dataset`",
|
|
1619
|
-
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
1620
|
-
)
|
|
1621
|
-
);
|
|
1622
|
-
return typeDef.studioUrl && typeof typeDef.studioUrl != "function" && problems.push(
|
|
1623
|
-
error(
|
|
1624
|
-
'The "studioUrl" property on a cross dataset reference must be a function taking "{id, type}" as argument and returning a studio url.',
|
|
1625
|
-
HELP_IDS.CROSS_DATASET_REFERENCE_INVALID
|
|
1626
|
-
)
|
|
1627
|
-
), problems.push(...getOptionErrors$2(typeDef)), {
|
|
1628
|
-
...typeDef,
|
|
1629
|
-
_problems: problems
|
|
1630
|
-
};
|
|
1631
|
-
};
|
|
1632
|
-
function getOptionErrors$2(typeDef) {
|
|
1633
|
-
const { options } = typeDef, problems = [];
|
|
1634
|
-
return problems.push(
|
|
1635
|
-
...["filter", "filterParams"].filter((key) => key in typeDef).map(
|
|
1636
|
-
(key) => error(
|
|
1637
|
-
`\`${key}\` is not allowed on a reference type definition - did you mean \`options.${key}\`?`,
|
|
1638
|
-
HELP_IDS.REFERENCE_INVALID_OPTIONS_LOCATION
|
|
1639
|
-
)
|
|
1640
|
-
)
|
|
1641
|
-
), options ? isPlainObject(options) ? typeof options.filter == "function" && typeof options.filterParams < "u" ? problems.concat(
|
|
1642
|
-
error(
|
|
1643
|
-
"`filterParams` cannot be used if `filter` is a function. Either statically define `filter` as a string, or return `params` from the `filter`-function.",
|
|
1644
|
-
HELP_IDS.REFERENCE_INVALID_FILTER_PARAMS_COMBINATION
|
|
1645
|
-
)
|
|
1646
|
-
) : typeof options.filter == "function" || !options.filter && !options.filterParams ? problems : typeof options.filter != "string" ? problems.concat(
|
|
1647
|
-
error(`If set, \`filter\` must be a string. Got ${typeof options.filter}`)
|
|
1648
|
-
) : typeof options.filterParams < "u" && !isPlainObject(options.filterParams) ? problems.concat(error("If set, `filterParams` must be an object.")) : options.filterParams ? problems.concat(
|
|
1649
|
-
Object.keys(options.filterParams).filter((key) => key.startsWith("__") || key.startsWith("$")).map((key) => error(`Filter parameter cannot be prefixed with "$" or "__". Got ${key}".`))
|
|
1650
|
-
) : problems : problems.concat(
|
|
1651
|
-
error(
|
|
1652
|
-
"The reference type expects `options` to be an object",
|
|
1653
|
-
HELP_IDS.REFERENCE_INVALID_OPTIONS
|
|
1654
|
-
)
|
|
1655
|
-
) : problems;
|
|
1656
|
-
}
|
|
1657
|
-
const REACT_SYM_RE = /^Symbol\(react\..+\)$/;
|
|
1658
|
-
function isComponentLike(value) {
|
|
1659
|
-
return typeof value == "function" || typeof value?.$$typeof == "symbol" && REACT_SYM_RE.test(String(value?.$$typeof));
|
|
1660
|
-
}
|
|
1661
|
-
function validateComponent(typeDef) {
|
|
1662
|
-
const components = "components" in typeDef ? typeDef.components : !1;
|
|
1663
|
-
if (!components)
|
|
1664
|
-
return [];
|
|
1665
|
-
const warnings = [];
|
|
1666
|
-
return components.input && !isComponentLike(components.input) && warnings.push(
|
|
1667
|
-
warning(
|
|
1668
|
-
`The \`components.input\` property is set but does not appear to be a valid React component (expected a function, but saw ${inspect(
|
|
1669
|
-
components.input
|
|
1670
|
-
)}). If you have imported a custom input component, please verify that you have imported the correct named/default export.`
|
|
1671
|
-
)
|
|
1672
|
-
), components.field && !isComponentLike(components.field) && warnings.push(
|
|
1673
|
-
warning(
|
|
1674
|
-
`The \`components.field\` property is set but does not appear to be a valid React component (expected a function, but saw ${inspect(
|
|
1675
|
-
components.field
|
|
1676
|
-
)}). If you have imported a custom field component, please verify that you have imported the correct named/default export.`
|
|
1677
|
-
)
|
|
1678
|
-
), components.item && !isComponentLike(components.item) && warnings.push(
|
|
1679
|
-
warning(
|
|
1680
|
-
`The \`components.item\` property is set but does not appear to be a valid React component (expected a function, but saw ${inspect(
|
|
1681
|
-
components.item
|
|
1682
|
-
)}). If you have imported a custom item component, please verify that you have imported the correct named/default export.`
|
|
1683
|
-
)
|
|
1684
|
-
), components.preview && !isComponentLike(components.preview) && warnings.push(
|
|
1685
|
-
warning(
|
|
1686
|
-
`The \`components.preview\` property is set but does not appear to be a valid React component (expected a function, but saw ${inspect(
|
|
1687
|
-
components.preview
|
|
1688
|
-
)}). If you have imported a custom preview component, please verify that you have imported the correct named/default export.`
|
|
1689
|
-
)
|
|
1690
|
-
), warnings;
|
|
1691
|
-
}
|
|
1692
|
-
const VALID_FIELD_RE = /^[A-Za-z]+[0-9A-Za-z_]*$/, CONVENTIONAL_FIELD_RE = /^[A-Za-z_]+[0-9A-Za-z_]*$/;
|
|
1693
|
-
function validateFieldName(name) {
|
|
1694
|
-
return typeof name != "string" ? [
|
|
1695
|
-
error(
|
|
1696
|
-
`Field names must be strings. Saw "${inspect(name)}"`,
|
|
1697
|
-
HELP_IDS.OBJECT_FIELD_NAME_INVALID
|
|
1698
|
-
)
|
|
1699
|
-
] : name.startsWith("_") ? [
|
|
1700
|
-
error(
|
|
1701
|
-
`Invalid field name "${name}". Field names cannot start with underscores "_" as it's reserved for system fields.`,
|
|
1702
|
-
HELP_IDS.OBJECT_FIELD_NAME_INVALID
|
|
1703
|
-
)
|
|
1704
|
-
] : VALID_FIELD_RE.test(name) ? CONVENTIONAL_FIELD_RE.test(name) ? [] : [
|
|
1705
|
-
warning(
|
|
1706
|
-
"Thats an interesting field name for sure! But it is... how to put it... a bit... unconventional? It may be wise to keep special characters out of field names for easier access later on."
|
|
1707
|
-
),
|
|
1708
|
-
HELP_IDS.OBJECT_FIELD_NAME_INVALID
|
|
1709
|
-
] : [
|
|
1710
|
-
error(
|
|
1711
|
-
`Invalid field name: "${name}". Fields can only contain characters from A-Z, numbers and underscores and should not start with a number (must pass the regular expression ${String(
|
|
1712
|
-
VALID_FIELD_RE
|
|
1713
|
-
)}).`,
|
|
1714
|
-
HELP_IDS.OBJECT_FIELD_NAME_INVALID
|
|
1715
|
-
)
|
|
1716
|
-
];
|
|
1717
|
-
}
|
|
1718
|
-
function validateField(field, _visitorContext) {
|
|
1719
|
-
if (!isPlainObject(field))
|
|
1720
|
-
return [
|
|
1721
|
-
error(
|
|
1722
|
-
`Incorrect type for field definition - should be an object, saw ${inspect(field)}`,
|
|
1723
|
-
HELP_IDS.OBJECT_FIELD_DEFINITION_INVALID_TYPE
|
|
1724
|
-
)
|
|
1725
|
-
];
|
|
1726
|
-
const problems = [];
|
|
1727
|
-
return problems.push(
|
|
1728
|
-
..."name" in field ? validateFieldName(field.name) : [error("Missing field name", HELP_IDS.OBJECT_FIELD_NAME_INVALID)]
|
|
1729
|
-
), problems.push(...validateComponent(field)), problems;
|
|
1730
|
-
}
|
|
1731
|
-
function getDuplicateFields(array2) {
|
|
1732
|
-
const dupes = {};
|
|
1733
|
-
return array2.forEach((field) => {
|
|
1734
|
-
dupes[field.name] || (dupes[field.name] = []), dupes[field.name].push(field);
|
|
1735
|
-
}), Object.keys(dupes).map((fieldName) => dupes[fieldName].length > 1 ? dupes[fieldName] : null).filter(Boolean);
|
|
1736
|
-
}
|
|
1737
|
-
function validateFields(fields, options = { allowEmpty: !1 }) {
|
|
1738
|
-
const problems = [];
|
|
1739
|
-
if (!Array.isArray(fields))
|
|
1740
|
-
return [
|
|
1741
|
-
error(
|
|
1742
|
-
`The "fields" property must be an array of fields. Instead saw "${typeof fields}"`,
|
|
1743
|
-
HELP_IDS.OBJECT_FIELDS_INVALID
|
|
1744
|
-
)
|
|
1745
|
-
];
|
|
1746
|
-
const fieldsWithNames = fields.filter((field) => typeof field.name == "string");
|
|
1747
|
-
getDuplicateFields(fieldsWithNames).forEach((dupes) => {
|
|
1748
|
-
problems.push(
|
|
1749
|
-
error(
|
|
1750
|
-
`Found ${dupes.length} fields with name "${dupes[0].name}" in object`,
|
|
1751
|
-
HELP_IDS.OBJECT_FIELD_NOT_UNIQUE
|
|
1752
|
-
)
|
|
1753
|
-
);
|
|
1754
|
-
}), fields.length === 0 && !options.allowEmpty && problems.push(error("Object should have at least one field", HELP_IDS.OBJECT_FIELDS_INVALID));
|
|
1755
|
-
const standaloneBlockFields = fields.filter((field) => field.type === "block").map((field) => `"${field.name}"`);
|
|
1756
|
-
if (standaloneBlockFields.length > 0) {
|
|
1757
|
-
const fmtFields = standaloneBlockFields.join(", ");
|
|
1758
|
-
problems.push(
|
|
1759
|
-
error(
|
|
1760
|
-
`Invalid standalone block field(s) ${fmtFields}. Block content must be defined as an array of blocks`,
|
|
1761
|
-
HELP_IDS.STANDALONE_BLOCK_TYPE
|
|
1762
|
-
)
|
|
1763
|
-
);
|
|
1764
|
-
}
|
|
1765
|
-
return problems;
|
|
1766
|
-
}
|
|
1767
|
-
function validatePreview(preview) {
|
|
1768
|
-
return isPlainObject(preview) ? typeof preview.prepare < "u" && typeof preview.prepare != "function" ? [
|
|
1769
|
-
error(
|
|
1770
|
-
`The "preview.prepare" property must be a function, instead saw "${typeof preview.prepare}"`
|
|
1771
|
-
)
|
|
1772
|
-
] : preview.select ? isPlainObject(preview.select) ? Object.keys(preview.select).reduce((errs, key) => typeof preview.select[key] == "string" ? errs : errs.concat(
|
|
1773
|
-
error(
|
|
1774
|
-
`The key "${key}" of "preview.select" must be a string, instead saw "${typeof preview.select[key]}"`
|
|
1775
|
-
)
|
|
1776
|
-
), []) : [
|
|
1777
|
-
error(
|
|
1778
|
-
`The "preview.select" property must be an object, instead saw "${typeof preview.prepare}"`
|
|
1779
|
-
)
|
|
1780
|
-
] : [] : [error(`The "preview" property must be an object, instead saw "${typeof preview}"`)];
|
|
1781
|
-
}
|
|
1782
|
-
var object = (typeDef, visitorContext) => {
|
|
1783
|
-
let problems = validateFields(typeDef.fields), preview = typeDef.preview;
|
|
1784
|
-
if (preview) {
|
|
1785
|
-
const previewErrors = validatePreview(typeDef.preview);
|
|
1786
|
-
problems = problems.concat(previewErrors), preview = previewErrors.some((err) => err.severity === "error") ? {} : preview;
|
|
1787
|
-
}
|
|
1788
|
-
return typeDef.type !== "document" && typeDef.type !== "object" && typeof typeDef.initialValue < "u" && problems.push(
|
|
1789
|
-
error('The "initialValue" property is currently only supported for document & object types.')
|
|
1790
|
-
), {
|
|
1791
|
-
...typeDef,
|
|
1792
|
-
preview,
|
|
1793
|
-
fields: (Array.isArray(typeDef.fields) ? typeDef.fields : []).map((field, index) => {
|
|
1794
|
-
const { name, ...fieldTypeDef } = field, { _problems, ...fieldType } = visitorContext.visit(fieldTypeDef, index);
|
|
1795
|
-
return {
|
|
1796
|
-
name,
|
|
1797
|
-
...fieldType,
|
|
1798
|
-
_problems: validateField(field).concat(_problems || [])
|
|
1799
|
-
};
|
|
1800
|
-
}),
|
|
1801
|
-
_problems: problems
|
|
1802
|
-
};
|
|
1803
|
-
}, documentVisitor = (typeDefinition, visitorContext) => {
|
|
1804
|
-
const typeDef = object(typeDefinition, visitorContext), { initialValue, initialValues } = typeDef;
|
|
1805
|
-
return typeof initialValue < "u" && !isPlainObject(initialValue) && typeof initialValue != "function" && typeDef._problems.push(
|
|
1806
|
-
error('The "initialValue" property must be either a plain object or a function')
|
|
1807
|
-
), typeof initialValues < "u" && typeDef._problems.push(error('Found property "initialValues" - did you mean "initialValue"?')), typeDef;
|
|
1808
|
-
}, file = (typeDef, visitorContext) => {
|
|
1809
|
-
const problems = [], fields = typeDef.fields;
|
|
1810
|
-
fields && problems.push(...validateFields(fields, { allowEmpty: !0 }));
|
|
1811
|
-
const invalidFieldNames = Array.isArray(fields) ? fields?.filter((field) => field.name === "asset") : [];
|
|
1812
|
-
return typeDef.options && typeof typeDef.options.metadata < "u" && !Array.isArray(typeDef.options.metadata) ? problems.push(
|
|
1813
|
-
error(
|
|
1814
|
-
"Invalid type for file `metadata` field - must be an array of strings",
|
|
1815
|
-
HELP_IDS.ASSET_METADATA_FIELD_INVALID
|
|
1816
|
-
)
|
|
1817
|
-
) : invalidFieldNames.length > 0 && problems.push(error("The name `asset` is not a valid field name for type `file`.")), {
|
|
1818
|
-
...typeDef,
|
|
1819
|
-
fields: (Array.isArray(fields) ? fields : []).map((field, index) => {
|
|
1820
|
-
const { name, ...fieldTypeDef } = field, { _problems, ...fieldType } = visitorContext.visit(fieldTypeDef, index);
|
|
1821
|
-
return {
|
|
1822
|
-
name,
|
|
1823
|
-
...fieldType,
|
|
1824
|
-
_problems: validateField(field).concat(_problems || [])
|
|
1825
|
-
};
|
|
1826
|
-
}),
|
|
1827
|
-
_problems: problems
|
|
1828
|
-
};
|
|
1829
|
-
};
|
|
1830
|
-
function normalizeToProp$1(typeDef) {
|
|
1831
|
-
return Array.isArray(typeDef.to) ? typeDef.to : typeDef.to ? [typeDef.to] : [];
|
|
1832
|
-
}
|
|
1833
|
-
function isValidResourceType(resourceType) {
|
|
1834
|
-
return resourceType ? resourceType != "media-library" && resourceType != "dataset" ? 'The resource type must be either "media-library" or "dataset"' : !0 : "The resource type must be a non-empty string";
|
|
1835
|
-
}
|
|
1836
|
-
function isValidResourceId(resourceType, resourceId) {
|
|
1837
|
-
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";
|
|
1838
|
-
}
|
|
1839
|
-
var globalDocumentReference = (typeDef, visitorContext) => {
|
|
1840
|
-
const isValidTo = Array.isArray(typeDef.to) || isPlainObject(typeDef.to), normalizedTo = normalizeToProp$1(typeDef), problems = flatten([
|
|
1841
|
-
isValidTo ? getDupes(normalizedTo, (t) => `${t.name};${t.type}`).map(
|
|
1842
|
-
(dupes) => error(
|
|
1843
|
-
`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`,
|
|
1844
|
-
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1845
|
-
)
|
|
1846
|
-
) : error(
|
|
1847
|
-
'The global document reference type is missing or having an invalid value for the required "to" property. It should be an array of accepted types.',
|
|
1848
|
-
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1849
|
-
)
|
|
1850
|
-
]);
|
|
1851
|
-
if (isValidTo && normalizedTo.length === 0 && problems.push(
|
|
1852
|
-
error(
|
|
1853
|
-
'The global document reference type should define at least one referenced type. Please check the "to" property.',
|
|
1854
|
-
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1855
|
-
)
|
|
1856
|
-
), normalizedTo.forEach((crossDatasetTypeDef, index) => {
|
|
1857
|
-
crossDatasetTypeDef.type || problems.push(
|
|
1858
|
-
error(
|
|
1859
|
-
`The referenced type at index ${index} must be named. Specify the name of the type you want to create references to.`,
|
|
1860
|
-
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1861
|
-
)
|
|
1862
|
-
), isPlainObject(crossDatasetTypeDef.preview) || problems.push(
|
|
1863
|
-
error(
|
|
1864
|
-
`Missing required preview config for the referenced type "${crossDatasetTypeDef.type || "<unknown type>"}"`,
|
|
1865
|
-
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1866
|
-
)
|
|
1867
|
-
);
|
|
1868
|
-
}), typeof typeDef.resourceType == "string") {
|
|
1869
|
-
const validation = isValidResourceType(typeDef.resourceType);
|
|
1870
|
-
validation !== !0 && problems.push(error(validation, HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID));
|
|
1871
|
-
} else
|
|
1872
|
-
problems.push(
|
|
1873
|
-
error(
|
|
1874
|
-
"A global document reference must specify a `resourceType`",
|
|
1875
|
-
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1876
|
-
)
|
|
1877
|
-
);
|
|
1878
|
-
if (typeof typeDef.resourceId == "string") {
|
|
1879
|
-
const datasetValidation = isValidResourceId(typeDef.resourceType, typeDef.resourceId);
|
|
1880
|
-
datasetValidation !== !0 && problems.push(error(datasetValidation, HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID));
|
|
1881
|
-
} else
|
|
1882
|
-
problems.push(
|
|
1883
|
-
error(
|
|
1884
|
-
"A global document reference must specify a `resourceId`",
|
|
1885
|
-
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1886
|
-
)
|
|
1887
|
-
);
|
|
1888
|
-
return typeDef.studioUrl && typeof typeDef.studioUrl != "function" && typeof typeDef.studioUrl != "string" && problems.push(
|
|
1889
|
-
error(
|
|
1890
|
-
'The "studioUrl" property on a global document reference must either be a function taking "{id, type}" as argument and returning a studio url, or a string being the base url pointing to a studio.',
|
|
1891
|
-
HELP_IDS.GLOBAL_DOCUMENT_REFERENCE_INVALID
|
|
1892
|
-
)
|
|
1893
|
-
), problems.push(...getOptionErrors$1(typeDef)), {
|
|
1894
|
-
...typeDef,
|
|
1895
|
-
_problems: problems
|
|
1896
|
-
};
|
|
1897
|
-
};
|
|
1898
|
-
function getOptionErrors$1(typeDef) {
|
|
1899
|
-
const { options } = typeDef, problems = [];
|
|
1900
|
-
return problems.push(
|
|
1901
|
-
...["filter", "filterParams"].filter((key) => key in typeDef).map(
|
|
1902
|
-
(key) => error(
|
|
1903
|
-
`\`${key}\` is not allowed on a reference type definition - did you mean \`options.${key}\`?`,
|
|
1904
|
-
HELP_IDS.REFERENCE_INVALID_OPTIONS_LOCATION
|
|
1905
|
-
)
|
|
1906
|
-
)
|
|
1907
|
-
), options ? isPlainObject(options) ? typeof options.filter == "function" && typeof options.filterParams < "u" ? problems.concat(
|
|
1908
|
-
error(
|
|
1909
|
-
"`filterParams` cannot be used if `filter` is a function. Either statically define `filter` as a string, or return `params` from the `filter`-function.",
|
|
1910
|
-
HELP_IDS.REFERENCE_INVALID_FILTER_PARAMS_COMBINATION
|
|
1911
|
-
)
|
|
1912
|
-
) : typeof options.filter == "function" || !options.filter && !options.filterParams ? problems : typeof options.filter != "string" ? problems.concat(
|
|
1913
|
-
error(`If set, \`filter\` must be a string. Got ${typeof options.filter}`)
|
|
1914
|
-
) : typeof options.filterParams < "u" && !isPlainObject(options.filterParams) ? problems.concat(error("If set, `filterParams` must be an object.")) : options.filterParams ? problems.concat(
|
|
1915
|
-
Object.keys(options.filterParams).filter((key) => key.startsWith("__") || key.startsWith("$")).map((key) => error(`Filter parameter cannot be prefixed with "$" or "__". Got ${key}".`))
|
|
1916
|
-
) : problems : problems.concat(
|
|
1917
|
-
error(
|
|
1918
|
-
"The reference type expects `options` to be an object",
|
|
1919
|
-
HELP_IDS.REFERENCE_INVALID_OPTIONS
|
|
1920
|
-
)
|
|
1921
|
-
) : problems;
|
|
1922
|
-
}
|
|
1923
|
-
const autoMeta = ["dimensions", "hasAlpha", "isOpaque"];
|
|
1924
|
-
var image = (typeDef, visitorContext) => {
|
|
1925
|
-
const problems = [], fields = typeDef.fields;
|
|
1926
|
-
fields && problems.push(...validateFields(fields, { allowEmpty: !0 }));
|
|
1927
|
-
let options = typeDef.options;
|
|
1928
|
-
const metadata = options?.metadata, superfluousMeta = Array.isArray(metadata) ? metadata.filter((meta) => autoMeta.includes(meta)) : [], invalidFieldNames = ["asset", "hotspot", "crop"], fieldsWithInvalidName = Array.isArray(fields) ? fields?.filter((field) => invalidFieldNames.includes(field.name)) : [];
|
|
1929
|
-
return typeof metadata < "u" && !Array.isArray(metadata) ? problems.push(
|
|
1930
|
-
error(
|
|
1931
|
-
"Invalid type for image `metadata` field - must be an array of strings",
|
|
1932
|
-
HELP_IDS.ASSET_METADATA_FIELD_INVALID
|
|
1933
|
-
)
|
|
1934
|
-
) : superfluousMeta.length > 0 ? (problems.push(
|
|
1935
|
-
warning(
|
|
1936
|
-
`Image \`metadata\` field contains superfluous properties (they are always included): ${superfluousMeta.join(
|
|
1937
|
-
", "
|
|
1938
|
-
)}`
|
|
1939
|
-
)
|
|
1940
|
-
), options = { ...options, metadata: metadata.filter((meta) => !autoMeta.includes(meta)) }) : fieldsWithInvalidName.length > 0 && problems.push(
|
|
1941
|
-
error(
|
|
1942
|
-
`The names \`${invalidFieldNames.join(
|
|
1943
|
-
"`, `"
|
|
1944
|
-
)}\` are invalid field names for type \`image\`.`
|
|
1945
|
-
)
|
|
1946
|
-
), {
|
|
1947
|
-
...typeDef,
|
|
1948
|
-
options,
|
|
1949
|
-
fields: (Array.isArray(fields) ? fields : []).map((field, index) => {
|
|
1950
|
-
const { name, ...fieldTypeDef } = field, { _problems, ...fieldType } = visitorContext.visit(fieldTypeDef, index);
|
|
1951
|
-
return {
|
|
1952
|
-
name,
|
|
1953
|
-
...fieldType,
|
|
1954
|
-
_problems: validateField(field).concat(_problems || [])
|
|
1955
|
-
};
|
|
1956
|
-
}),
|
|
1957
|
-
_problems: problems
|
|
1958
|
-
};
|
|
1959
|
-
};
|
|
1960
|
-
function normalizeToProp(typeDef) {
|
|
1961
|
-
return Array.isArray(typeDef.to) ? typeDef.to : typeDef.to ? [typeDef.to] : typeDef.to;
|
|
1962
|
-
}
|
|
1963
|
-
var reference = (typeDef, visitorContext) => {
|
|
1964
|
-
const isValidTo = Array.isArray(typeDef.to) || isPlainObject(typeDef.to), normalizedTo = normalizeToProp(typeDef), problems = flatten([
|
|
1965
|
-
isValidTo ? getDupes(normalizedTo, (t) => `${t.name};${t.type}`).map(
|
|
1966
|
-
(dupes) => error(
|
|
1967
|
-
`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`,
|
|
1968
|
-
HELP_IDS.REFERENCE_TO_INVALID
|
|
1969
|
-
)
|
|
1970
|
-
) : error(
|
|
1971
|
-
'The reference type is missing or having an invalid value for the required "to" property. It should be an array of accepted types.',
|
|
1972
|
-
HELP_IDS.REFERENCE_TO_INVALID
|
|
1973
|
-
)
|
|
1974
|
-
]);
|
|
1975
|
-
return isValidTo && normalizedTo.length === 0 && problems.push(
|
|
1976
|
-
error(
|
|
1977
|
-
'The reference type should define at least one accepted type. Please check the "to" property.',
|
|
1978
|
-
HELP_IDS.REFERENCE_TO_INVALID
|
|
1979
|
-
)
|
|
1980
|
-
), problems.push(...getOptionErrors(typeDef)), {
|
|
1981
|
-
...typeDef,
|
|
1982
|
-
to: (isValidTo ? normalizedTo : []).map(visitorContext.visit),
|
|
1983
|
-
_problems: problems
|
|
1984
|
-
};
|
|
1985
|
-
};
|
|
1986
|
-
function getOptionErrors(typeDef) {
|
|
1987
|
-
const { options } = typeDef, problems = [];
|
|
1988
|
-
return problems.push(
|
|
1989
|
-
...["filter", "filterParams"].filter((key) => key in typeDef).map(
|
|
1990
|
-
(key) => error(
|
|
1991
|
-
`\`${key}\` is not allowed on a reference type definition - did you mean \`options.${key}\`?`,
|
|
1992
|
-
HELP_IDS.REFERENCE_INVALID_OPTIONS_LOCATION
|
|
1993
|
-
)
|
|
1994
|
-
)
|
|
1995
|
-
), options ? isPlainObject(options) ? typeof options.filter == "function" && typeof options.filterParams < "u" ? problems.concat(
|
|
1996
|
-
error(
|
|
1997
|
-
"`filterParams` cannot be used if `filter` is a function. Either statically define `filter` as a string, or return `params` from the `filter`-function.",
|
|
1998
|
-
HELP_IDS.REFERENCE_INVALID_FILTER_PARAMS_COMBINATION
|
|
1999
|
-
)
|
|
2000
|
-
) : typeof options.filter == "function" || !options.filter && !options.filterParams ? problems : typeof options.filter != "string" ? problems.concat(
|
|
2001
|
-
error(`If set, \`filter\` must be a string. Got ${typeof options.filter}`)
|
|
2002
|
-
) : typeof options.filterParams < "u" && !isPlainObject(options.filterParams) ? problems.concat(error("If set, `filterParams` must be an object.")) : options.filterParams ? problems.concat(
|
|
2003
|
-
Object.keys(options.filterParams).filter((key) => key.startsWith("__") || key.startsWith("$")).map((key) => error(`Filter parameter cannot be prefixed with "$" or "__". Got ${key}".`))
|
|
2004
|
-
) : problems : problems.concat(
|
|
2005
|
-
error(
|
|
2006
|
-
"The reference type expects `options` to be an object",
|
|
2007
|
-
HELP_IDS.REFERENCE_INVALID_OPTIONS
|
|
2008
|
-
)
|
|
2009
|
-
) : problems;
|
|
2010
|
-
}
|
|
2011
|
-
var rootType = (typeDef, visitorContext) => {
|
|
2012
|
-
const hasName = !!typeDef.name;
|
|
2013
|
-
if (!hasName && Object.keys(typeDef).length === 1)
|
|
2014
|
-
return {
|
|
2015
|
-
...typeDef,
|
|
2016
|
-
_problems: [
|
|
2017
|
-
error(
|
|
2018
|
-
"Invalid/undefined type declaration, check declaration or the import/export of the schema type.",
|
|
2019
|
-
HELP_IDS.TYPE_INVALID
|
|
2020
|
-
)
|
|
2021
|
-
]
|
|
2022
|
-
};
|
|
2023
|
-
const problems = [];
|
|
2024
|
-
return looksLikeEsmModule(typeDef) ? problems.push(
|
|
2025
|
-
error(
|
|
2026
|
-
"Type appears to be an ES6 module imported through CommonJS require - use an import statement or access the `.default` property",
|
|
2027
|
-
HELP_IDS.TYPE_IS_ESM_MODULE
|
|
2028
|
-
)
|
|
2029
|
-
) : hasName ? visitorContext.isReserved(typeDef.name) && problems.push(
|
|
2030
|
-
error(
|
|
2031
|
-
`Invalid type name: "${typeDef.name}" is a reserved name.`,
|
|
2032
|
-
HELP_IDS.TYPE_NAME_RESERVED
|
|
2033
|
-
)
|
|
2034
|
-
) : problems.push(error("Missing type name", HELP_IDS.TYPE_MISSING_NAME)), visitorContext.isDuplicate(typeDef.name) && problems.push(
|
|
2035
|
-
error(
|
|
2036
|
-
`Invalid type name: A type with name "${typeDef.name}" is already defined in the schema.`
|
|
2037
|
-
)
|
|
2038
|
-
), 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)), {
|
|
2039
|
-
...typeDef,
|
|
2040
|
-
_problems: problems
|
|
2041
|
-
};
|
|
2042
|
-
};
|
|
2043
|
-
function looksLikeEsmModule(typeDef) {
|
|
2044
|
-
return !typeDef.name && typeDef.default && (typeDef.default.name || typeDef.default.title);
|
|
2045
|
-
}
|
|
2046
|
-
var slug = (typeDef, visitorContext) => {
|
|
2047
|
-
const problems = [];
|
|
2048
|
-
return typeDef.options && typeDef.options.slugifyFn && (problems.push(
|
|
2049
|
-
warning(
|
|
2050
|
-
'Heads up! The "slugifyFn" option has been renamed to "slugify".',
|
|
2051
|
-
HELP_IDS.SLUG_SLUGIFY_FN_RENAMED
|
|
2052
|
-
)
|
|
2053
|
-
), typeDef.options.slugify = typeDef.options.slugifyFn), {
|
|
2054
|
-
...typeDef,
|
|
2055
|
-
_problems: problems
|
|
2056
|
-
};
|
|
2057
|
-
};
|
|
2058
|
-
const typeVisitors = {
|
|
2059
|
-
array,
|
|
2060
|
-
object,
|
|
2061
|
-
slug,
|
|
2062
|
-
file,
|
|
2063
|
-
image,
|
|
2064
|
-
block: validateBlockType,
|
|
2065
|
-
document: documentVisitor,
|
|
2066
|
-
reference,
|
|
2067
|
-
crossDatasetReference,
|
|
2068
|
-
globalDocumentReference
|
|
2069
|
-
}, getNoopVisitor = (visitorContext) => (schemaDef) => ({
|
|
2070
|
-
name: `<unnamed_type_@_index_${visitorContext.index}>`,
|
|
2071
|
-
...schemaDef,
|
|
2072
|
-
_problems: []
|
|
2073
|
-
});
|
|
2074
|
-
function combine(...visitors) {
|
|
2075
|
-
return (schemaType, visitorContext) => visitors.reduce(
|
|
2076
|
-
(result, visitor) => {
|
|
2077
|
-
const res = visitor(result, visitorContext);
|
|
2078
|
-
return {
|
|
2079
|
-
...res,
|
|
2080
|
-
_problems: result._problems.concat(res._problems)
|
|
2081
|
-
};
|
|
2082
|
-
},
|
|
2083
|
-
{ _problems: [], ...schemaType }
|
|
2084
|
-
);
|
|
2085
|
-
}
|
|
2086
|
-
function validateSchema(schemaTypes, { transformTypeVisitors = (visitors) => visitors } = {}) {
|
|
2087
|
-
return traverseSanitySchema(schemaTypes, (schemaDef, visitorContext) => {
|
|
2088
|
-
const typeVisitor = schemaDef && schemaDef.type && transformTypeVisitors(typeVisitors)[schemaDef.type] || getNoopVisitor(visitorContext);
|
|
2089
|
-
return visitorContext.isRoot ? combine(rootType, common, typeVisitor)(schemaDef, visitorContext) : combine(common, typeVisitor)(schemaDef, visitorContext);
|
|
2090
|
-
});
|
|
2091
|
-
}
|
|
2092
|
-
function unsupportedTypeValidator(typeLabel) {
|
|
2093
|
-
return function() {
|
|
2094
|
-
return {
|
|
2095
|
-
_problems: [
|
|
2096
|
-
{
|
|
2097
|
-
severity: "error",
|
|
2098
|
-
message: `Type unsupported in Media Library aspects: ${typeLabel}.`
|
|
2099
|
-
}
|
|
2100
|
-
]
|
|
2101
|
-
};
|
|
2102
|
-
};
|
|
2103
|
-
}
|
|
2104
|
-
function validateMediaLibraryAssetAspect(maybeAspect) {
|
|
2105
|
-
const validated = validateSchema([maybeAspect], {
|
|
2106
|
-
transformTypeVisitors: (typeVisitors2) => ({
|
|
2107
|
-
...typeVisitors2,
|
|
2108
|
-
document: unsupportedTypeValidator("document"),
|
|
2109
|
-
image: unsupportedTypeValidator("image"),
|
|
2110
|
-
file: unsupportedTypeValidator("file"),
|
|
2111
|
-
video: unsupportedTypeValidator("sanity.video"),
|
|
2112
|
-
reference: unsupportedTypeValidator("reference"),
|
|
2113
|
-
crossDatasetReference: unsupportedTypeValidator("cross dataset reference")
|
|
2114
|
-
})
|
|
2115
|
-
}), errors = groupProblems(validated.getTypes()).map((group) => group.problems.filter(({ severity }) => severity === "error")).filter((problems) => problems.length);
|
|
2116
|
-
return [errors.length === 0, errors];
|
|
2117
|
-
}
|
|
2118
|
-
export {
|
|
2119
|
-
DEFAULT_MAX_FIELD_DEPTH,
|
|
2120
|
-
DescriptorConverter,
|
|
2121
|
-
builtinTypes,
|
|
2122
|
-
extractSchema,
|
|
2123
|
-
groupProblems,
|
|
2124
|
-
isActionEnabled,
|
|
2125
|
-
processSchemaSynchronization,
|
|
2126
|
-
resolveSearchConfig,
|
|
2127
|
-
resolveSearchConfigForBaseFieldPaths,
|
|
2128
|
-
validateMediaLibraryAssetAspect,
|
|
2129
|
-
validateSchema
|
|
2130
|
-
};
|
|
2131
|
-
//# sourceMappingURL=_internal.mjs.map
|