@sanity/schema 5.0.0-next-major.20251216093854 → 5.0.0-next-major.20251216101132
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/lib/_internal.d.ts +13 -0
- package/lib/_internal.js +58 -13
- package/lib/_internal.js.map +1 -1
- package/package.json +6 -6
package/lib/_internal.d.ts
CHANGED
|
@@ -233,6 +233,19 @@ export declare class DescriptorConverter {
|
|
|
233
233
|
): Promise<SetSynchronization<RegistryType>>
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Extracts a GROQ-compatible schema from a Sanity schema definition. The extraction happens in three passes:
|
|
238
|
+
*
|
|
239
|
+
* 1. **Dependency analysis & hoisting detection** (`sortByDependencies`): Walks the entire schema to sort
|
|
240
|
+
* types topologically and identifies inline object fields that are used multiple times (candidates
|
|
241
|
+
* for "hoisting").
|
|
242
|
+
*
|
|
243
|
+
* 2. **Hoisted type creation**: For any repeated inline fields, we create top-level named type definitions
|
|
244
|
+
* first, so they exist before being referenced.
|
|
245
|
+
*
|
|
246
|
+
* 3. **Main type conversion**: Processes each schema type in dependency order. When a field was marked for
|
|
247
|
+
* hoisting, we emit an `inline` reference to the hoisted type instead of duplicating the structure.
|
|
248
|
+
*/
|
|
236
249
|
export declare function extractSchema(
|
|
237
250
|
schemaDef: Schema,
|
|
238
251
|
extractOptions?: ExtractSchemaOptions,
|
package/lib/_internal.js
CHANGED
|
@@ -2314,15 +2314,32 @@ const documentDefaultFields = (typeName) => ({
|
|
|
2314
2314
|
["email", { type: "string" }]
|
|
2315
2315
|
]);
|
|
2316
2316
|
function extractSchema(schemaDef, extractOptions = {}) {
|
|
2317
|
-
const inlineFields = /* @__PURE__ */ new Set(), documentTypes = /* @__PURE__ */ new Map(), schema = [], generatedTypes = /* @__PURE__ */ new Map(), sortedSchemaTypeNames = sortByDependencies(schemaDef);
|
|
2318
|
-
|
|
2317
|
+
const inlineFields = /* @__PURE__ */ new Set(), documentTypes = /* @__PURE__ */ new Map(), schema = [], generatedTypes = /* @__PURE__ */ new Map(), { sortedSchemaTypeNames, repeated } = sortByDependencies(schemaDef);
|
|
2318
|
+
repeated.forEach((key, objectField) => {
|
|
2319
|
+
const base = convertSchemaType(objectField.type);
|
|
2320
|
+
if (base !== null) {
|
|
2321
|
+
if (base.type === "inline") {
|
|
2322
|
+
repeated.delete(objectField);
|
|
2323
|
+
return;
|
|
2324
|
+
}
|
|
2325
|
+
if (base.type === "unknown") {
|
|
2326
|
+
repeated.delete(objectField);
|
|
2327
|
+
return;
|
|
2328
|
+
}
|
|
2329
|
+
schema.push({
|
|
2330
|
+
type: "type",
|
|
2331
|
+
name: getGeneratedTypeName(key),
|
|
2332
|
+
value: base
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
}), sortedSchemaTypeNames.forEach((typeName) => {
|
|
2319
2336
|
const schemaType = schemaDef.get(typeName);
|
|
2320
2337
|
if (schemaType === void 0)
|
|
2321
2338
|
return;
|
|
2322
2339
|
const base = convertBaseType(schemaType);
|
|
2323
2340
|
base !== null && (base.type === "type" && inlineFields.add(schemaType), base.type === "document" && documentTypes.set(typeName, base), schema.push(base));
|
|
2324
2341
|
});
|
|
2325
|
-
function getGeneratedTypeName(typeName, suffix) {
|
|
2342
|
+
function getGeneratedTypeName(typeName, suffix = "") {
|
|
2326
2343
|
const name = generatedTypes.get(typeName);
|
|
2327
2344
|
if (name) return name;
|
|
2328
2345
|
for (let i = 0; i < 5; i++) {
|
|
@@ -2395,10 +2412,19 @@ function extractSchema(schemaDef, extractOptions = {}) {
|
|
|
2395
2412
|
function createObject(schemaType) {
|
|
2396
2413
|
const attributes = {}, fields = gatherFields(schemaType);
|
|
2397
2414
|
for (const field of fields) {
|
|
2398
|
-
const fieldIsRequired = isFieldRequired(field?.type?.validation)
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2415
|
+
const fieldIsRequired = isFieldRequired(field?.type?.validation);
|
|
2416
|
+
let value;
|
|
2417
|
+
const hoisted = repeated.get(field), isTopLevelSchemaType = sortedSchemaTypeNames.includes(field.type.name);
|
|
2418
|
+
if (hoisted && !isTopLevelSchemaType)
|
|
2419
|
+
value = {
|
|
2420
|
+
type: "inline",
|
|
2421
|
+
name: getGeneratedTypeName(hoisted)
|
|
2422
|
+
};
|
|
2423
|
+
else {
|
|
2424
|
+
if (value = convertSchemaType(field.type), value === null)
|
|
2425
|
+
continue;
|
|
2426
|
+
hasAssetRequired(field?.type?.validation) && value.type === "object" && (value.attributes.asset.optional = !1);
|
|
2427
|
+
}
|
|
2402
2428
|
const optional = extractOptions.enforceRequiredFields ? fieldIsRequired === !1 : !0;
|
|
2403
2429
|
attributes[field.name] = {
|
|
2404
2430
|
type: "objectAttribute",
|
|
@@ -2576,8 +2602,16 @@ function lastType(typeDef) {
|
|
|
2576
2602
|
}
|
|
2577
2603
|
}
|
|
2578
2604
|
function sortByDependencies(compiledSchema) {
|
|
2579
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2580
|
-
function
|
|
2605
|
+
const seen = /* @__PURE__ */ new Set(), objectMap = /* @__PURE__ */ new Set(), repeated = /* @__PURE__ */ new Map(), repeatedNames = /* @__PURE__ */ new Set();
|
|
2606
|
+
function pickRepeatedName(path) {
|
|
2607
|
+
for (let idx = path.length - 1; idx >= 0; idx--) {
|
|
2608
|
+
const name = path.slice(idx).join(".");
|
|
2609
|
+
if (!repeatedNames.has(name))
|
|
2610
|
+
return repeatedNames.add(name), name;
|
|
2611
|
+
}
|
|
2612
|
+
throw new Error(`Unable to pick repeated name: ${path.join(".")}`);
|
|
2613
|
+
}
|
|
2614
|
+
function walkDependencies(schemaType, dependencies, path, hoistRepetitions = !0) {
|
|
2581
2615
|
if (!seen.has(schemaType)) {
|
|
2582
2616
|
if (seen.add(schemaType), "fields" in schemaType)
|
|
2583
2617
|
for (const field of gatherFields(schemaType)) {
|
|
@@ -2587,11 +2621,19 @@ function sortByDependencies(compiledSchema) {
|
|
|
2587
2621
|
continue;
|
|
2588
2622
|
}
|
|
2589
2623
|
let schemaTypeName;
|
|
2590
|
-
schemaType.type.type ? schemaTypeName = field.type.type.name : "jsonType" in schemaType.type && (schemaTypeName = field.type.jsonType), schemaTypeName === "object" || schemaTypeName === "block"
|
|
2624
|
+
if (schemaType.type.type ? schemaTypeName = field.type.type.name : "jsonType" in schemaType.type && (schemaTypeName = field.type.jsonType), schemaTypeName === "object" || schemaTypeName === "block") {
|
|
2625
|
+
if (isReferenceType(field.type))
|
|
2626
|
+
field.type.to.forEach((ref) => dependencies.add(ref.type));
|
|
2627
|
+
else if (dependencies.add(field.type), hoistRepetitions && !validSchemaNames.has(field.type.name)) {
|
|
2628
|
+
const fieldPath = path.concat([field.name]);
|
|
2629
|
+
!repeated.has(field) && objectMap.has(field) && repeated.set(field, pickRepeatedName(fieldPath)), objectMap.add(field);
|
|
2630
|
+
}
|
|
2631
|
+
} else field.type && dependencies.add(field.type);
|
|
2632
|
+
walkDependencies(field.type, dependencies, path.concat([field.name]));
|
|
2591
2633
|
}
|
|
2592
2634
|
else if ("of" in schemaType)
|
|
2593
2635
|
for (const item of schemaType.of)
|
|
2594
|
-
walkDependencies(item, dependencies);
|
|
2636
|
+
walkDependencies(item, dependencies, path.concat(item.name), !isReferenceType(schemaType));
|
|
2595
2637
|
}
|
|
2596
2638
|
}
|
|
2597
2639
|
const dependencyMap = /* @__PURE__ */ new Map(), schemaTypeNames = compiledSchema.getTypeNames(), validSchemaNames = /* @__PURE__ */ new Set();
|
|
@@ -2601,7 +2643,7 @@ function sortByDependencies(compiledSchema) {
|
|
|
2601
2643
|
return;
|
|
2602
2644
|
validSchemaNames.add(typeName);
|
|
2603
2645
|
const dependencies = /* @__PURE__ */ new Set();
|
|
2604
|
-
walkDependencies(schemaType, dependencies), dependencyMap.set(schemaType, dependencies), seen.clear();
|
|
2646
|
+
walkDependencies(schemaType, dependencies, [typeName]), dependencyMap.set(schemaType, dependencies), seen.clear();
|
|
2605
2647
|
});
|
|
2606
2648
|
const typeNames = [], currentlyVisiting = /* @__PURE__ */ new Set(), visited = /* @__PURE__ */ new Set();
|
|
2607
2649
|
function visit(type) {
|
|
@@ -2613,7 +2655,10 @@ function sortByDependencies(compiledSchema) {
|
|
|
2613
2655
|
}
|
|
2614
2656
|
for (const [type] of dependencyMap)
|
|
2615
2657
|
visit(type);
|
|
2616
|
-
return
|
|
2658
|
+
return {
|
|
2659
|
+
sortedSchemaTypeNames: typeNames.filter((typeName) => validSchemaNames.has(typeName)),
|
|
2660
|
+
repeated
|
|
2661
|
+
};
|
|
2617
2662
|
}
|
|
2618
2663
|
function validateNoCallbacks(typeDef) {
|
|
2619
2664
|
const problems = [];
|