@sanity/schema 5.14.0-next.14 → 5.14.0-next.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,8 @@
1
1
  import { a as SchemaValidationResult, i as ProblemPathTypeSegment, l as Schema$1, n as ProblemPathPropertySegment, o as TypeWithProblems, r as ProblemPathSegment, s as _FIXME_, t as ProblemPath } from "./_chunks-dts/typedefs.js";
2
2
  import { SetSynchronization, SynchronizationRequest, SynchronizationResult } from "@sanity/descriptors";
3
3
  import * as _sanity_types0 from "@sanity/types";
4
- import { Schema, SchemaType, SchemaTypeDefinition, SchemaValidationProblem, SchemaValidationProblemGroup } from "@sanity/types";
4
+ import { SanityDocumentLike, Schema, SchemaType, SchemaTypeDefinition, SchemaValidationProblem, SchemaValidationProblemGroup } from "@sanity/types";
5
+ import { ComponentType, ReactNode } from "react";
5
6
  import { SchemaType as SchemaType$1 } from "groq-js";
6
7
  /** The scheduler is capable of executing work in different ways. */
7
8
  type Scheduler = {
@@ -44,6 +45,180 @@ declare function resolveSearchConfigForBaseFieldPaths(type: any, maxDepth?: numb
44
45
  */
45
46
  declare function resolveSearchConfig(type: any, maxDepth?: number): any;
46
47
  declare const ALL_FIELDS_GROUP_NAME = "all-fields";
48
+ declare function createSchemaFromManifestTypes(schemaDef: {
49
+ name: string;
50
+ types: unknown[];
51
+ }): Schema$1;
52
+ interface MediaLibraryConfig {
53
+ enabled?: boolean;
54
+ libraryId?: string;
55
+ __internal?: {
56
+ frontendHost?: string;
57
+ };
58
+ }
59
+ declare const SANITY_WORKSPACE_SCHEMA_ID_PREFIX = "_.schemas";
60
+ declare const SANITY_WORKSPACE_SCHEMA_TYPE = "system.schema";
61
+ declare const CURRENT_WORKSPACE_SCHEMA_VERSION = "2025-05-01";
62
+ type ManifestSerializable = string | number | boolean | {
63
+ [k: string]: ManifestSerializable;
64
+ } | ManifestSerializable[];
65
+ interface CreateManifest {
66
+ version: number;
67
+ createdAt: string;
68
+ workspaces: ManifestWorkspaceFile[];
69
+ studioVersion: string | null;
70
+ }
71
+ interface ManifestWorkspaceFile extends Omit<CreateWorkspaceManifest, 'schema' | 'tools'> {
72
+ schema: string;
73
+ tools: string;
74
+ }
75
+ interface CreateWorkspaceManifest {
76
+ name: string;
77
+ title?: string;
78
+ subtitle?: string;
79
+ basePath: string;
80
+ dataset: string;
81
+ projectId: string;
82
+ mediaLibrary?: MediaLibraryConfig;
83
+ schema: ManifestSchemaType[];
84
+ tools: ManifestTool[];
85
+ /**
86
+ * returns undefined in the case of the icon not being able to be stringified
87
+ */
88
+ icon: string | undefined;
89
+ }
90
+ interface ManifestSchemaType {
91
+ type: string;
92
+ name: string;
93
+ title?: string;
94
+ deprecated?: {
95
+ reason: string;
96
+ };
97
+ readOnly?: boolean | 'conditional';
98
+ hidden?: boolean | 'conditional';
99
+ validation?: ManifestValidationGroup[];
100
+ fields?: ManifestField[];
101
+ to?: ManifestReferenceMember[];
102
+ of?: ManifestArrayMember[];
103
+ preview?: {
104
+ select: Record<string, string>;
105
+ };
106
+ fieldsets?: ManifestFieldset[];
107
+ options?: Record<string, ManifestSerializable>;
108
+ marks?: {
109
+ annotations?: ManifestArrayMember[];
110
+ decorators?: ManifestTitledValue[];
111
+ };
112
+ lists?: ManifestTitledValue[];
113
+ styles?: ManifestTitledValue[];
114
+ }
115
+ interface ManifestFieldset {
116
+ name: string;
117
+ title?: string;
118
+ [index: string]: ManifestSerializable | undefined;
119
+ }
120
+ interface ManifestTitledValue {
121
+ value: string;
122
+ title?: string;
123
+ }
124
+ type ManifestField = ManifestSchemaType & {
125
+ fieldset?: string;
126
+ };
127
+ type ManifestArrayMember = Omit<ManifestSchemaType, 'name'> & {
128
+ name?: string;
129
+ };
130
+ type ManifestReferenceMember = Omit<ManifestSchemaType, 'name'> & {
131
+ name?: string;
132
+ };
133
+ interface ManifestValidationGroup {
134
+ rules: ManifestValidationRule[];
135
+ message?: string;
136
+ level?: 'error' | 'warning' | 'info';
137
+ }
138
+ type ManifestValidationRule = {
139
+ flag: string;
140
+ constraint?: ManifestSerializable;
141
+ [index: string]: ManifestSerializable | undefined;
142
+ };
143
+ interface ManifestTool {
144
+ name: string;
145
+ title: string;
146
+ /**
147
+ * returns undefined in the case of the icon not being able to be stringified
148
+ */
149
+ icon: string | undefined;
150
+ type: string | null;
151
+ }
152
+ type DefaultWorkspaceSchemaId = `${typeof SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.${string}`;
153
+ type PrefixedWorkspaceSchemaId = `${DefaultWorkspaceSchemaId}.${string}`;
154
+ type WorkspaceSchemaId = DefaultWorkspaceSchemaId | PrefixedWorkspaceSchemaId;
155
+ interface StoredWorkspaceSchema extends SanityDocumentLike {
156
+ _type: typeof SANITY_WORKSPACE_SCHEMA_TYPE;
157
+ _id: WorkspaceSchemaId;
158
+ version: typeof CURRENT_WORKSPACE_SCHEMA_VERSION | undefined;
159
+ tag?: string;
160
+ workspace: {
161
+ name: string;
162
+ title?: string;
163
+ };
164
+ /**
165
+ * The API expects JSON coming in, but will store a string to save on attribute paths.
166
+ * Consumers must use JSON.parse on the value, put we deploy to the API using ManifestSchemaType[]
167
+ */
168
+ schema: string | ManifestSchemaType[];
169
+ }
170
+ interface ManifestWorkspaceInput {
171
+ name: string;
172
+ title?: string;
173
+ subtitle?: string;
174
+ basePath: string;
175
+ projectId: string;
176
+ dataset: string;
177
+ icon?: ComponentType | ReactNode;
178
+ mediaLibrary?: MediaLibraryConfig;
179
+ schema: Schema;
180
+ tools: ManifestToolInput[];
181
+ }
182
+ interface ManifestToolInput {
183
+ title: string;
184
+ name: string;
185
+ icon?: ComponentType | ReactNode;
186
+ __internalApplicationType?: string;
187
+ }
188
+ type IconResolver = (props: {
189
+ icon?: ComponentType | ReactNode;
190
+ title: string;
191
+ subtitle?: string;
192
+ }) => string | undefined | Promise<string | undefined>;
193
+ declare function extractCreateWorkspaceManifest(workspace: ManifestWorkspaceInput, iconResolver?: IconResolver): Promise<CreateWorkspaceManifest>;
194
+ /**
195
+ * Extracts all serializable properties from userland schema types,
196
+ * so they best-effort can be used as definitions for Schema.compile
197
+ . */
198
+ declare function extractManifestSchemaTypes(schema: Schema): ManifestSchemaType[];
199
+ declare const validForNamesChars = "a-zA-Z0-9_-";
200
+ declare const validForNamesPattern: RegExp;
201
+ declare function getWorkspaceSchemaId(args: {
202
+ workspaceName: string;
203
+ tag?: string;
204
+ }): {
205
+ safeBaseId: DefaultWorkspaceSchemaId;
206
+ safeTaggedId: WorkspaceSchemaId;
207
+ idWarning: string | undefined;
208
+ };
209
+ interface ParsedWorkspaceSchemaId {
210
+ schemaId: string;
211
+ workspace: string;
212
+ }
213
+ declare function parseWorkspaceSchemaId(id: string, errors: string[]): ParsedWorkspaceSchemaId | undefined;
214
+ declare function createStoredWorkspaceSchemaPayload(args: {
215
+ workspace: {
216
+ name: string;
217
+ title?: string;
218
+ };
219
+ schema: ManifestSchemaType[];
220
+ tag?: string;
221
+ }): Omit<StoredWorkspaceSchema, '_id' | '_type'>;
47
222
  declare const builtinTypes: ({
48
223
  name: string;
49
224
  title: string;
@@ -240,10 +415,6 @@ declare const builtinTypes: ({
240
415
  readOnly: boolean;
241
416
  })[];
242
417
  })[];
243
- declare function createSchemaFromManifestTypes(schemaDef: {
244
- name: string;
245
- types: unknown[];
246
- }): Schema$1;
247
418
  interface ExtractSchemaOptions {
248
419
  enforceRequiredFields?: boolean;
249
420
  }
@@ -311,4 +482,4 @@ declare class ValidationError extends Error {
311
482
  problems: SchemaValidationProblemGroup[];
312
483
  constructor(problems: SchemaValidationProblemGroup[]);
313
484
  }
314
- export { ALL_FIELDS_GROUP_NAME, DEFAULT_MAX_FIELD_DEPTH, DescriptorConverter, type _FIXME_ as FIXME, type SchemaValidationResult as Problem, type SchemaValidationResult as ValidationResult, type ProblemPath, type ProblemPathPropertySegment, type ProblemPathSegment, type ProblemPathTypeSegment, SchemaSynchronizationRequest, SchemaSynchronizationResult, type TypeWithProblems, ValidationError, builtinTypes, createSchemaFromManifestTypes, extractSchema, groupProblems, isActionEnabled, processSchemaSynchronization, resolveSearchConfig, resolveSearchConfigForBaseFieldPaths, validateMediaLibraryAssetAspect, validateSchema };
485
+ export { ALL_FIELDS_GROUP_NAME, type CreateManifest, type CreateWorkspaceManifest, DEFAULT_MAX_FIELD_DEPTH, type DefaultWorkspaceSchemaId, DescriptorConverter, type _FIXME_ as FIXME, type IconResolver, type ManifestSchemaType, type ManifestWorkspaceFile, type ParsedWorkspaceSchemaId, type SchemaValidationResult as Problem, type SchemaValidationResult as ValidationResult, type ProblemPath, type ProblemPathPropertySegment, type ProblemPathSegment, type ProblemPathTypeSegment, SchemaSynchronizationRequest, SchemaSynchronizationResult, type StoredWorkspaceSchema, type TypeWithProblems, ValidationError, type WorkspaceSchemaId, builtinTypes, createSchemaFromManifestTypes, createStoredWorkspaceSchemaPayload, extractCreateWorkspaceManifest, extractManifestSchemaTypes, extractSchema, getWorkspaceSchemaId, groupProblems, isActionEnabled, parseWorkspaceSchemaId, processSchemaSynchronization, resolveSearchConfig, resolveSearchConfigForBaseFieldPaths, validForNamesChars, validForNamesPattern, validateMediaLibraryAssetAspect, validateSchema };
package/lib/_internal.js CHANGED
@@ -14,6 +14,7 @@ import isPlainObject from "lodash-es/isPlainObject.js";
14
14
  import omit from "lodash-es/omit.js";
15
15
  import leven from "leven";
16
16
  import inspect from "object-inspect";
17
+ import startCase from "lodash-es/startCase.js";
17
18
  import { createReferenceTypeNode } from "groq-js";
18
19
  const MAX_IDLE_WORK = 8.333333333333334;
19
20
  class IdleScheduler {
@@ -2350,6 +2351,405 @@ function stringToRegExp(str) {
2350
2351
  const match = str.match(/^\/(.*)\/([gimuy]*)$/);
2351
2352
  return match ? new RegExp(match[1], match[2]) : new RegExp(str);
2352
2353
  }
2354
+ const DEFAULT_IMAGE_FIELDS = ["asset", "hotspot", "crop", "media"], DEFAULT_FILE_FIELDS = ["asset", "media"], DEFAULT_GEOPOINT_FIELDS = ["lat", "lng", "alt"], DEFAULT_SLUG_FIELDS = ["current", "source"];
2355
+ function getCustomFields(type) {
2356
+ const fields = type.fieldsets ? type.fieldsets.flatMap((fs) => fs.single ? fs.field : fs.fields.map((field) => ({
2357
+ ...field,
2358
+ fieldset: fs.name
2359
+ }))) : type.fields;
2360
+ return isType$1(type, "block") ? [] : isType$1(type, "slug") ? fields.filter((f) => !DEFAULT_SLUG_FIELDS.includes(f.name)) : isType$1(type, "geopoint") ? fields.filter((f) => !DEFAULT_GEOPOINT_FIELDS.includes(f.name)) : isType$1(type, "image") ? fields.filter((f) => !DEFAULT_IMAGE_FIELDS.includes(f.name)) : isType$1(type, "file") ? fields.filter((f) => !DEFAULT_FILE_FIELDS.includes(f.name)) : fields;
2361
+ }
2362
+ function isReference(type) {
2363
+ return isType$1(type, "reference");
2364
+ }
2365
+ function isCrossDatasetReference(type) {
2366
+ return isType$1(type, "crossDatasetReference");
2367
+ }
2368
+ function isGlobalDocumentReference(type) {
2369
+ return isType$1(type, "globalDocumentReference");
2370
+ }
2371
+ function isObjectField(maybeOjectField) {
2372
+ return typeof maybeOjectField == "object" && maybeOjectField !== null && "name" in maybeOjectField;
2373
+ }
2374
+ function isCustomized(maybeCustomized) {
2375
+ const internalOwnProps = getSchemaTypeInternalOwnProps(maybeCustomized);
2376
+ return isObjectField(maybeCustomized) && !isReference(maybeCustomized) && !isCrossDatasetReference(maybeCustomized) && !isGlobalDocumentReference(maybeCustomized) && "fields" in maybeCustomized && Array.isArray(maybeCustomized.fields) && // needed to differentiate inline, named array object types from globally defined types
2377
+ // we only consider it customized if the _definition_ has fields declared
2378
+ // this holds for all customizable object-like types: object, document, image and file
2379
+ internalOwnProps?.fields ? !!getCustomFields(maybeCustomized).length : !1;
2380
+ }
2381
+ function isType$1(schemaType, typeName) {
2382
+ return schemaType.name === typeName ? !0 : schemaType.type ? isType$1(schemaType.type, typeName) : !1;
2383
+ }
2384
+ function isDefined(value) {
2385
+ return value != null;
2386
+ }
2387
+ function isRecord(value) {
2388
+ return !!value && typeof value == "object";
2389
+ }
2390
+ function isPrimitive(value) {
2391
+ return isString(value) || isBoolean(value) || isNumber(value);
2392
+ }
2393
+ function isString(value) {
2394
+ return typeof value == "string";
2395
+ }
2396
+ function isNumber(value) {
2397
+ return typeof value == "number";
2398
+ }
2399
+ function isBoolean(value) {
2400
+ return typeof value == "boolean";
2401
+ }
2402
+ function getSchemaTypeInternalOwnProps(type) {
2403
+ return type?._internal_ownProps;
2404
+ }
2405
+ function getDefinedTypeName(type) {
2406
+ return getSchemaTypeInternalOwnProps(type)?.type;
2407
+ }
2408
+ const MAX_CUSTOM_PROPERTY_DEPTH = 5, noopIconResolver = () => {
2409
+ };
2410
+ async function extractCreateWorkspaceManifest(workspace, iconResolver = noopIconResolver) {
2411
+ const serializedSchema = extractManifestSchemaTypes(workspace.schema), serializedTools = await extractManifestTools(workspace.tools, iconResolver);
2412
+ return {
2413
+ name: workspace.name,
2414
+ title: workspace.title,
2415
+ subtitle: workspace.subtitle,
2416
+ basePath: workspace.basePath,
2417
+ projectId: workspace.projectId,
2418
+ dataset: workspace.dataset,
2419
+ icon: await iconResolver({
2420
+ icon: workspace.icon,
2421
+ title: workspace.title ?? workspace.name,
2422
+ subtitle: workspace.subtitle
2423
+ }),
2424
+ mediaLibrary: workspace.mediaLibrary,
2425
+ schema: serializedSchema,
2426
+ tools: serializedTools
2427
+ };
2428
+ }
2429
+ function extractManifestSchemaTypes(schema) {
2430
+ const typeNames = schema.getTypeNames(), studioDefaultTypeNames = Schema.compile({
2431
+ name: "default",
2432
+ types: builtinTypes
2433
+ }).getTypeNames();
2434
+ return typeNames.filter((typeName) => !studioDefaultTypeNames.includes(typeName)).map((typeName) => schema.get(typeName)).filter((type) => typeof type < "u").map((type) => transformType(type));
2435
+ }
2436
+ function transformCommonTypeFields(type, typeName, context) {
2437
+ const arrayProps = typeName === "array" && type.jsonType === "array" ? transformArrayMember(type) : {}, referenceProps = isReference(type) ? transformReference(type) : {}, crossDatasetRefProps = isCrossDatasetReference(type) ? transformCrossDatasetReference(type) : {}, globalRefProps = isGlobalDocumentReference(type) ? transformGlobalDocumentReference(type) : {}, objectFields = type.jsonType === "object" && type.type && isCustomized(type) ? {
2438
+ fields: getCustomFields(type).map((objectField) => transformField(objectField))
2439
+ } : {};
2440
+ return {
2441
+ ...retainCustomTypeProps(type),
2442
+ ...transformValidation(type.validation),
2443
+ ...ensureString("description", type.description),
2444
+ ...objectFields,
2445
+ ...arrayProps,
2446
+ ...referenceProps,
2447
+ ...crossDatasetRefProps,
2448
+ ...globalRefProps,
2449
+ ...ensureConditional("readOnly", type.readOnly),
2450
+ ...ensureConditional("hidden", type.hidden),
2451
+ ...transformFieldsets(type),
2452
+ // fieldset prop gets instrumented via getCustomFields
2453
+ ...ensureString("fieldset", type.fieldset),
2454
+ ...transformBlockType(type)
2455
+ };
2456
+ }
2457
+ function transformFieldsets(type) {
2458
+ if (type.jsonType !== "object")
2459
+ return {};
2460
+ const fieldsets = type.fieldsets?.filter((fs) => !fs.single).map((fs) => {
2461
+ const options = isRecord(fs.options) ? { options: retainSerializableProps(fs.options) } : {};
2462
+ return {
2463
+ name: fs.name,
2464
+ ...ensureCustomTitle(fs.name, fs.title),
2465
+ ...ensureString("description", fs.description),
2466
+ ...ensureConditional("readOnly", fs.readOnly),
2467
+ ...ensureConditional("hidden", fs.hidden),
2468
+ ...options
2469
+ };
2470
+ });
2471
+ return fieldsets?.length ? { fieldsets } : {};
2472
+ }
2473
+ function transformType(type, context) {
2474
+ const typeName = type.type ? type.type.name : type.jsonType;
2475
+ return {
2476
+ ...transformCommonTypeFields(type, typeName),
2477
+ name: type.name,
2478
+ type: typeName,
2479
+ ...ensureCustomTitle(type.name, type.title)
2480
+ };
2481
+ }
2482
+ function retainCustomTypeProps(type) {
2483
+ const manuallySerializedFields = [
2484
+ //explicitly added
2485
+ "name",
2486
+ "title",
2487
+ "description",
2488
+ "readOnly",
2489
+ "hidden",
2490
+ "validation",
2491
+ "fieldsets",
2492
+ "fields",
2493
+ "to",
2494
+ "of",
2495
+ // not serialized
2496
+ "type",
2497
+ "jsonType",
2498
+ "__experimental_actions",
2499
+ "__experimental_formPreviewTitle",
2500
+ "__experimental_omnisearch_visibility",
2501
+ "__experimental_search",
2502
+ "components",
2503
+ "icon",
2504
+ "orderings",
2505
+ "preview",
2506
+ "groups",
2507
+ //only exists on fields
2508
+ "group"
2509
+ // we know about these, but let them be generically handled
2510
+ // deprecated
2511
+ // rows (from text)
2512
+ // initialValue
2513
+ // options
2514
+ // crossDatasetReference props
2515
+ ], typeWithoutManuallyHandledFields = Object.fromEntries(
2516
+ Object.entries(type).filter(
2517
+ ([key]) => !manuallySerializedFields.includes(key)
2518
+ )
2519
+ );
2520
+ return retainSerializableProps(typeWithoutManuallyHandledFields);
2521
+ }
2522
+ function retainSerializableProps(maybeSerializable, depth = 0) {
2523
+ if (!(depth > MAX_CUSTOM_PROPERTY_DEPTH) && isDefined(maybeSerializable)) {
2524
+ if (isPrimitive(maybeSerializable))
2525
+ return maybeSerializable === "" ? void 0 : maybeSerializable;
2526
+ if (maybeSerializable instanceof RegExp)
2527
+ return maybeSerializable.toString();
2528
+ if (Array.isArray(maybeSerializable)) {
2529
+ const arrayItems = maybeSerializable.map((item) => retainSerializableProps(item, depth + 1)).filter((item) => isDefined(item));
2530
+ return arrayItems.length ? arrayItems : void 0;
2531
+ }
2532
+ if (isRecord(maybeSerializable)) {
2533
+ const serializableEntries = Object.entries(maybeSerializable).map(([key, value]) => [key, retainSerializableProps(value, depth + 1)]).filter(([, value]) => isDefined(value));
2534
+ return serializableEntries.length ? Object.fromEntries(serializableEntries) : void 0;
2535
+ }
2536
+ }
2537
+ }
2538
+ function transformField(field, context) {
2539
+ const fieldType = field.type, typeName = getDefinedTypeName(fieldType) ?? fieldType.name;
2540
+ return {
2541
+ ...transformCommonTypeFields(fieldType, typeName),
2542
+ name: field.name,
2543
+ type: typeName,
2544
+ ...ensureCustomTitle(field.name, fieldType.title),
2545
+ // this prop gets added synthetically via getCustomFields
2546
+ ...ensureString("fieldset", field.fieldset)
2547
+ };
2548
+ }
2549
+ function transformArrayMember(arrayMember, context) {
2550
+ return {
2551
+ of: arrayMember.of.map((type) => {
2552
+ const typeName = getDefinedTypeName(type) ?? type.name;
2553
+ return {
2554
+ ...transformCommonTypeFields(type, typeName),
2555
+ type: typeName,
2556
+ ...typeName === type.name ? {} : { name: type.name },
2557
+ ...ensureCustomTitle(type.name, type.title)
2558
+ };
2559
+ })
2560
+ };
2561
+ }
2562
+ function transformReference(reference2) {
2563
+ return {
2564
+ to: (reference2.to ?? []).map((type) => ({
2565
+ ...retainCustomTypeProps(type),
2566
+ type: type.name
2567
+ }))
2568
+ };
2569
+ }
2570
+ function transformCrossDatasetReference(reference2) {
2571
+ return {
2572
+ to: (reference2.to ?? []).map((crossDataset) => {
2573
+ const preview = crossDataset.preview?.select ? { preview: { select: crossDataset.preview.select } } : {};
2574
+ return {
2575
+ type: crossDataset.type,
2576
+ ...ensureCustomTitle(crossDataset.type, crossDataset.title),
2577
+ ...preview
2578
+ };
2579
+ })
2580
+ };
2581
+ }
2582
+ function transformGlobalDocumentReference(reference2) {
2583
+ return {
2584
+ to: (reference2.to ?? []).map((crossDataset) => {
2585
+ const preview = crossDataset.preview?.select ? { preview: { select: crossDataset.preview.select } } : {};
2586
+ return {
2587
+ type: crossDataset.type,
2588
+ ...ensureCustomTitle(crossDataset.type, crossDataset.title),
2589
+ ...preview
2590
+ };
2591
+ })
2592
+ };
2593
+ }
2594
+ const transformTypeValidationRule = (rule) => ({
2595
+ ...rule,
2596
+ constraint: "constraint" in rule && (typeof rule.constraint == "string" ? rule.constraint.toLowerCase() : retainSerializableProps(rule.constraint))
2597
+ }), validationRuleTransformers = {
2598
+ type: transformTypeValidationRule
2599
+ };
2600
+ function transformValidation(validation) {
2601
+ const validationArray = (Array.isArray(validation) ? validation : [validation]).filter(
2602
+ (value) => typeof value == "object" && "_type" in value
2603
+ ), disallowedFlags = ["type"], disallowedConstraintTypes = [Rule.FIELD_REF], serializedValidation = validationArray.map(({ _rules, _message, _level }) => {
2604
+ const message = typeof _message == "string" ? { message: _message } : {};
2605
+ return {
2606
+ rules: _rules.filter((rule) => {
2607
+ if (!("constraint" in rule))
2608
+ return !1;
2609
+ const { flag, constraint } = rule;
2610
+ return disallowedFlags.includes(flag) ? !1 : !(typeof constraint == "object" && "type" in constraint && disallowedConstraintTypes.includes(constraint.type));
2611
+ }).reduce((rules, rule) => {
2612
+ const transformedRule = (validationRuleTransformers[rule.flag] ?? ((spec) => retainSerializableProps(spec)))(rule);
2613
+ return transformedRule ? [...rules, transformedRule] : rules;
2614
+ }, []),
2615
+ level: _level,
2616
+ ...message
2617
+ };
2618
+ }).filter((group) => !!group.rules.length);
2619
+ return serializedValidation.length ? { validation: serializedValidation } : {};
2620
+ }
2621
+ function ensureCustomTitle(typeName, value) {
2622
+ const titleObject = ensureString("title", value), defaultTitle = startCase(typeName);
2623
+ return titleObject.title === defaultTitle ? {} : titleObject;
2624
+ }
2625
+ function ensureString(key, value) {
2626
+ return typeof value == "string" ? {
2627
+ [key]: value
2628
+ } : {};
2629
+ }
2630
+ function ensureConditional(key, value) {
2631
+ return typeof value == "boolean" ? {
2632
+ [key]: value
2633
+ } : typeof value == "function" ? {
2634
+ [key]: "conditional"
2635
+ } : {};
2636
+ }
2637
+ function transformBlockType(blockType, context) {
2638
+ if (blockType.jsonType !== "object" || !isType$1(blockType, "block"))
2639
+ return {};
2640
+ const childrenField = blockType.fields?.find((field) => field.name === "children");
2641
+ if (!childrenField)
2642
+ return {};
2643
+ const ofType = childrenField.type.of;
2644
+ if (!ofType)
2645
+ return {};
2646
+ const spanType = ofType.find((memberType) => memberType.name === "span");
2647
+ if (!spanType)
2648
+ return {};
2649
+ const inlineObjectTypes = ofType.filter((memberType) => memberType.name !== "span") || [];
2650
+ return {
2651
+ marks: {
2652
+ annotations: spanType.annotations.map((t) => transformType(t)),
2653
+ decorators: resolveEnabledDecorators(spanType)
2654
+ },
2655
+ lists: resolveEnabledListItems(blockType),
2656
+ styles: resolveEnabledStyles(blockType),
2657
+ of: inlineObjectTypes.map((t) => transformType(t))
2658
+ };
2659
+ }
2660
+ function resolveEnabledStyles(blockType) {
2661
+ const styleField = blockType.fields?.find((btField) => btField.name === "style");
2662
+ return resolveTitleValueArray(styleField?.type?.options?.list);
2663
+ }
2664
+ function resolveEnabledDecorators(spanType) {
2665
+ return "decorators" in spanType ? resolveTitleValueArray(spanType.decorators) : void 0;
2666
+ }
2667
+ function resolveEnabledListItems(blockType) {
2668
+ const listField = blockType.fields?.find((btField) => btField.name === "listItem");
2669
+ return resolveTitleValueArray(listField?.type?.options?.list);
2670
+ }
2671
+ function resolveTitleValueArray(possibleArray) {
2672
+ if (!possibleArray || !Array.isArray(possibleArray))
2673
+ return;
2674
+ const titledValues = possibleArray.filter(
2675
+ (d) => isRecord(d) && !!d.value && isString(d.value)
2676
+ ).map((item) => ({
2677
+ value: item.value,
2678
+ ...ensureString("title", item.title)
2679
+ }));
2680
+ if (titledValues?.length)
2681
+ return titledValues;
2682
+ }
2683
+ const extractManifestTools = async (tools, iconResolver = noopIconResolver) => Promise.all(
2684
+ tools.map(async (tool) => {
2685
+ const { title, name, icon, __internalApplicationType: type } = tool;
2686
+ return {
2687
+ title,
2688
+ name,
2689
+ type: type || null,
2690
+ icon: await iconResolver({
2691
+ icon,
2692
+ title
2693
+ })
2694
+ };
2695
+ })
2696
+ ), SANITY_WORKSPACE_SCHEMA_ID_PREFIX = "_.schemas", CURRENT_WORKSPACE_SCHEMA_VERSION = "2025-05-01", validForNamesChars = "a-zA-Z0-9_-", validForNamesPattern = new RegExp(`^[${validForNamesChars}]+$`, "g"), validForIdChars = "a-zA-Z0-9._-", validForIdPattern = new RegExp(`^[${validForIdChars}]+$`, "g"), requiredInId = SANITY_WORKSPACE_SCHEMA_ID_PREFIX.replace(/[.]/g, "\\."), idPatternString = `^${requiredInId}\\.([${validForNamesChars}]+)`, baseIdPattern = new RegExp(`${idPatternString}$`), taggedIdPattern = new RegExp(`${idPatternString}\\.tag\\.([${validForNamesChars}]+)$`);
2697
+ function getWorkspaceSchemaId(args) {
2698
+ const { workspaceName: rawWorkspaceName, tag } = args;
2699
+ let workspaceName = rawWorkspaceName, idWarning;
2700
+ workspaceName.match(validForNamesPattern) || (workspaceName = workspaceName.replace(new RegExp(`[^${validForNamesChars}]`, "g"), "_"), idWarning = [
2701
+ `Workspace "${rawWorkspaceName}" contains characters unsupported by schema _id [${validForNamesChars}], they will be replaced with _.`,
2702
+ "This could lead duplicate schema ids: consider renaming your workspace."
2703
+ ].join(`
2704
+ `));
2705
+ const safeBaseId = `${SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.${workspaceName}`;
2706
+ return {
2707
+ safeBaseId,
2708
+ safeTaggedId: `${safeBaseId}${tag ? `.tag.${tag}` : ""}`,
2709
+ idWarning
2710
+ };
2711
+ }
2712
+ function parseWorkspaceSchemaId(id, errors) {
2713
+ const trimmedId = id.trim();
2714
+ if (!trimmedId.match(validForIdPattern)) {
2715
+ errors.push(`id can only contain characters in [${validForIdChars}] but found: "${trimmedId}"`);
2716
+ return;
2717
+ }
2718
+ if (trimmedId.startsWith("-")) {
2719
+ errors.push(`id cannot start with - (dash) but found: "${trimmedId}"`);
2720
+ return;
2721
+ }
2722
+ if (trimmedId.match(/\.\./g)) {
2723
+ errors.push(`id cannot have consecutive . (period) characters, but found: "${trimmedId}"`);
2724
+ return;
2725
+ }
2726
+ const [, workspace] = trimmedId.match(taggedIdPattern) ?? trimmedId.match(baseIdPattern) ?? [];
2727
+ if (!workspace) {
2728
+ errors.push(
2729
+ [
2730
+ `id must either match ${SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.<workspaceName> `,
2731
+ `or ${SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.<workspaceName>.tag.<tag> but found: "${trimmedId}". `,
2732
+ `Note that workspace name characters not in [${validForNamesChars}] has to be replaced with _ for schema id.`
2733
+ ].join("")
2734
+ );
2735
+ return;
2736
+ }
2737
+ return {
2738
+ schemaId: trimmedId,
2739
+ workspace
2740
+ };
2741
+ }
2742
+ function createStoredWorkspaceSchemaPayload(args) {
2743
+ return {
2744
+ version: CURRENT_WORKSPACE_SCHEMA_VERSION,
2745
+ tag: args.tag,
2746
+ workspace: {
2747
+ name: args.workspace.name,
2748
+ title: args.workspace.title
2749
+ },
2750
+ schema: args.schema
2751
+ };
2752
+ }
2353
2753
  const documentDefaultFields = (typeName) => ({
2354
2754
  _id: {
2355
2755
  type: "objectAttribute",
@@ -2950,12 +3350,19 @@ export {
2950
3350
  ValidationError,
2951
3351
  builtinTypes,
2952
3352
  createSchemaFromManifestTypes,
3353
+ createStoredWorkspaceSchemaPayload,
3354
+ extractCreateWorkspaceManifest,
3355
+ extractManifestSchemaTypes,
2953
3356
  extractSchema,
3357
+ getWorkspaceSchemaId,
2954
3358
  groupProblems,
2955
3359
  isActionEnabled,
3360
+ parseWorkspaceSchemaId,
2956
3361
  processSchemaSynchronization,
2957
3362
  resolveSearchConfig,
2958
3363
  resolveSearchConfigForBaseFieldPaths,
3364
+ validForNamesChars,
3365
+ validForNamesPattern,
2959
3366
  validateMediaLibraryAssetAspect,
2960
3367
  validateSchema
2961
3368
  };