sanity 6.2.0-next.143 → 6.2.0-next.144

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.
@@ -7299,8 +7299,8 @@ const slugValidator = async (value, context) => {
7299
7299
  object: !0,
7300
7300
  string: !0
7301
7301
  }, isRuleConstraint = (typeString2) => typeString2 in ruleConstraintTypes;
7302
- function getTypeChain$3(type, visited = /* @__PURE__ */ new Set()) {
7303
- return type ? visited.has(type) ? [] : (visited.add(type), [...type.type ? getTypeChain$3(type.type, visited) : [], type]) : [];
7302
+ function getTypeChain$4(type, visited = /* @__PURE__ */ new Set()) {
7303
+ return type ? visited.has(type) ? [] : (visited.add(type), [...type.type ? getTypeChain$4(type.type, visited) : [], type]) : [];
7304
7304
  }
7305
7305
  function baseRuleReducer(inputRule, type) {
7306
7306
  let baseRule = inputRule;
@@ -7333,7 +7333,7 @@ function normalizeValidationRules(typeDef, context) {
7333
7333
  }, context));
7334
7334
  const baseRule = (
7335
7335
  // using an object + Object.values to de-dupe the type chain by type name
7336
- Object.values(getTypeChain$3(typeDef).reduce((acc, type) => (acc[type.name] = type, acc), {})).reduce(baseRuleReducer, new Rule(typeDef))
7336
+ Object.values(getTypeChain$4(typeDef).reduce((acc, type) => (acc[type.name] = type, acc), {})).reduce(baseRuleReducer, new Rule(typeDef))
7337
7337
  );
7338
7338
  return validation2 && typeof validation2 == "object" ? [validation2] : validation2 ? typeof validation2 == "function" ? normalizeValidationRules({
7339
7339
  ...typeDef,
@@ -7592,7 +7592,7 @@ function validateItemObservable({
7592
7592
  }) : ancestorHiddenValue, hidden = resolveHiddenForType(type, value, parent, path, ancestorHidden), addUnknownFieldsValidator = (rule) => (
7593
7593
  // if the schema type is an object type
7594
7594
  type?.jsonType === "object" && // and if somewhere in it's type chain, it inherits from object or document
7595
- getTypeChain$3(type).find((t) => ["object", "document", "file", "image"].includes(t.name)) && // and the environment is not the studio
7595
+ getTypeChain$4(type).find((t) => ["object", "document", "file", "image"].includes(t.name)) && // and the environment is not the studio
7596
7596
  environment !== "studio" ? rule.custom(unknownFieldsValidator(type), {
7597
7597
  bypassConcurrencyLimit: !0
7598
7598
  }).warning() : rule
@@ -15699,7 +15699,7 @@ function isEmptyItem(value) {
15699
15699
  function isPlainObject(obj) {
15700
15700
  return obj !== null && typeof obj == "object" && obj.constructor === Object;
15701
15701
  }
15702
- function isSchemaType$3(obj) {
15702
+ function isSchemaType$4(obj) {
15703
15703
  return !(typeof obj != "object" || !obj || !("jsonType" in obj) || typeof obj.jsonType != "string" || !("name" in obj) || typeof obj.name != "string");
15704
15704
  }
15705
15705
  function identity$1(t) {
@@ -15715,7 +15715,7 @@ function createImmutableReconcile({
15715
15715
  const reconciled2 = curr.map((item, index) => immutableReconcile2(prev[index], item));
15716
15716
  return reconciled2.every((item, index) => item === prev[index]) ? prev : reconciled2;
15717
15717
  }
15718
- if (isSchemaType$3(prev) || isSchemaType$3(curr) || !isPlainObject(prev) || !isPlainObject(curr)) return curr;
15718
+ if (isSchemaType$4(prev) || isSchemaType$4(curr) || !isPlainObject(prev) || !isPlainObject(curr)) return curr;
15719
15719
  const prevObj = prev, currObj = curr, reconciled = {};
15720
15720
  let changed = !1;
15721
15721
  const enumerableKeys = new Set(Object.keys(currObj));
@@ -16642,11 +16642,11 @@ function getOption(type, optionName) {
16642
16642
  return get(type.options, optionName);
16643
16643
  }
16644
16644
  const PSEUDO_OBJECTS = ["array", "file", "image", "reference", "slug"], HIDDEN_FIELDS = ["asset", "crop", "hotspot", "_ref", "_weak", "media"], NO_LEVEL_LAYOUTS = ["tags"], NO_LEVEL_TYPES = ["slug"];
16645
- function getTypeChain$2(type, visited) {
16645
+ function getTypeChain$3(type, visited) {
16646
16646
  if (!type) return [];
16647
16647
  if (visited.has(type)) return [];
16648
16648
  visited.add(type);
16649
- const next = type.type ? getTypeChain$2(type.type, visited) : [];
16649
+ const next = type.type ? getTypeChain$3(type.type, visited) : [];
16650
16650
  return [type, ...next];
16651
16651
  }
16652
16652
  function getFieldLevel(schemaType, currentLevel) {
@@ -16766,7 +16766,7 @@ function* introspectSchema(schemaType, path, cache2 = /* @__PURE__ */ new WeakMa
16766
16766
  else {
16767
16767
  if (typeof headType > "u")
16768
16768
  throw new Error(`No type hint provided for polymorphic array segment: \`${JSON.stringify(headSegment)}\``);
16769
- headSchemaType = schemaType.of.find((type) => getTypeChain$2(type, /* @__PURE__ */ new Set()).some(({
16769
+ headSchemaType = schemaType.of.find((type) => getTypeChain$3(type, /* @__PURE__ */ new Set()).some(({
16770
16770
  name
16771
16771
  }) => name === headType));
16772
16772
  }
@@ -19014,7 +19014,7 @@ function defaultResolveFieldComponent(schemaType) {
19014
19014
  return BooleanField;
19015
19015
  if (isDateTimeSchemaType(schemaType))
19016
19016
  return DateTimeField;
19017
- const typeChain = getTypeChain$2(schemaType, /* @__PURE__ */ new Set());
19017
+ const typeChain = getTypeChain$3(schemaType, /* @__PURE__ */ new Set());
19018
19018
  return typeChain.some((t) => isDateTimeSchemaType(t)) ? DateTimeField : typeChain.some((t) => t.name === "image" || t.name === "file") ? ImageOrFileField : typeChain.some((t) => isCrossDatasetReferenceSchemaType(t)) || typeChain.some((t) => t.name === "slug") ? PrimitiveField$1 : typeChain.some((t) => isReferenceSchemaType(t)) ? ReferenceField : schemaType.jsonType !== "object" && schemaType.jsonType !== "array" ? PrimitiveField$1 : ObjectOrArrayField;
19019
19019
  }
19020
19020
  function is$1(typeName, type) {
@@ -19121,6 +19121,96 @@ function compileSortExpression(searchSort, index, options = {}) {
19121
19121
  projectionIndex: index
19122
19122
  };
19123
19123
  }
19124
+ const PREVIEW_FIELD_WEIGHT_MAP$2 = {
19125
+ title: 10,
19126
+ subtitle: 5,
19127
+ description: 1.5
19128
+ }, DEFAULT_PREVIEW_SELECT_WEIGHT = 5, CACHE$2 = /* @__PURE__ */ new WeakMap(), getTypeChain$2 = (type) => type ? [type, ...getTypeChain$2(type.type)] : [], isStringField$2 = (type) => type?.jsonType === "string", isPtField$2 = (type) => type?.jsonType === "array" && type.of.some((arrayMemberType) => getTypeChain$2(arrayMemberType).some(({
19129
+ name
19130
+ }) => name === "block")), isSlugField$2 = (type) => getTypeChain$2(type).some(({
19131
+ jsonType,
19132
+ name
19133
+ }) => jsonType === "object" && name === "slug");
19134
+ function isSchemaType$3(input) {
19135
+ return typeof input < "u" && "name" in input;
19136
+ }
19137
+ function findFieldType(type, fieldName) {
19138
+ for (const chainType of getTypeChain$2(type))
19139
+ if (chainType.jsonType === "object" && chainType.fields?.length) {
19140
+ const field = chainType.fields.find(({
19141
+ name
19142
+ }) => name === fieldName);
19143
+ if (field)
19144
+ return field.type;
19145
+ }
19146
+ }
19147
+ function resolveLeaf(type, segments, depth, maxDepth) {
19148
+ if (type === void 0 || depth > maxDepth)
19149
+ return;
19150
+ if (segments.length === 0)
19151
+ return isPtField$2(type) ? {
19152
+ leafPath: "",
19153
+ mapWith: "pt::text"
19154
+ } : isSlugField$2(type) && isStringField$2(findFieldType(type, "current")) ? {
19155
+ leafPath: "current"
19156
+ } : isStringField$2(type) ? {
19157
+ leafPath: ""
19158
+ } : void 0;
19159
+ const [head, ...rest] = segments, fieldType = findFieldType(type, head);
19160
+ if (fieldType === void 0 || isReferenceSchemaType(fieldType))
19161
+ return;
19162
+ const resolved = resolveLeaf(fieldType, rest, depth + 1, maxDepth);
19163
+ if (resolved !== void 0)
19164
+ return {
19165
+ leafPath: resolved.leafPath === "" ? head : `${head}.${resolved.leafPath}`,
19166
+ mapWith: resolved.mapWith
19167
+ };
19168
+ }
19169
+ function walkToReference(type, segments, depth, maxDepth) {
19170
+ if (type === void 0 || depth > maxDepth || segments.length === 0)
19171
+ return;
19172
+ const [head, ...rest] = segments, fieldType = findFieldType(type, head);
19173
+ if (fieldType !== void 0)
19174
+ return isReferenceSchemaType(fieldType) && "to" in fieldType ? {
19175
+ targetTypes: fieldType.to,
19176
+ leafSegments: rest
19177
+ } : walkToReference(fieldType, rest, depth + 1, maxDepth);
19178
+ }
19179
+ function deriveReferenceSearchSpecs({
19180
+ schemaType,
19181
+ maxDepth
19182
+ }) {
19183
+ if (!isSchemaType$3(schemaType))
19184
+ return [];
19185
+ const cachedByDepth = CACHE$2.get(schemaType) ?? /* @__PURE__ */ new Map(), cached = cachedByDepth.get(maxDepth);
19186
+ if (cached)
19187
+ return cached;
19188
+ const select2 = schemaType.preview?.select, byTargetAndLeaf = /* @__PURE__ */ new Map();
19189
+ for (const [selectionKey, rawPath] of Object.entries(select2 ?? {})) {
19190
+ if (rawPath.replace(/\.\d+/g, "[]").includes("[]"))
19191
+ continue;
19192
+ const boundary = walkToReference(schemaType, rawPath.split("."), 0, maxDepth);
19193
+ if (boundary === void 0 || boundary.leafSegments.length === 0)
19194
+ continue;
19195
+ const weight = PREVIEW_FIELD_WEIGHT_MAP$2[selectionKey] ?? DEFAULT_PREVIEW_SELECT_WEIGHT;
19196
+ for (const targetType of boundary.targetTypes) {
19197
+ const leaf = resolveLeaf(targetType, boundary.leafSegments, 0, maxDepth);
19198
+ if (leaf === void 0 || leaf.leafPath === "")
19199
+ continue;
19200
+ const dedupeKey = `${targetType.name}:${leaf.leafPath}`, existing = byTargetAndLeaf.get(dedupeKey);
19201
+ (existing === void 0 || existing.weight < weight) && byTargetAndLeaf.set(dedupeKey, {
19202
+ targetType: targetType.name,
19203
+ leafPath: leaf.leafPath,
19204
+ weight,
19205
+ ...leaf.mapWith ? {
19206
+ mapWith: leaf.mapWith
19207
+ } : {}
19208
+ });
19209
+ }
19210
+ }
19211
+ const specs = Array.from(byTargetAndLeaf.values());
19212
+ return cachedByDepth.set(maxDepth, specs), CACHE$2.set(schemaType, cachedByDepth), specs;
19213
+ }
19124
19214
  const CACHE$1 = /* @__PURE__ */ new WeakMap(), PREVIEW_FIELD_WEIGHT_MAP$1 = {
19125
19215
  title: 10,
19126
19216
  subtitle: 5,
@@ -19392,6 +19482,20 @@ function prefixLast(query) {
19392
19482
  const prefixedTokens = [...tokens];
19393
19483
  return prefixedTokens.splice(finalIncrementalTokenIndex, 1, `${finalIncrementalToken}*`), prefixedTokens.join(" ");
19394
19484
  }
19485
+ const REFERENCE_RESOLVE_LIMIT = 1e3;
19486
+ function createReferenceResolveQuery(specs, rawQuery) {
19487
+ return specs.length === 0 ? void 0 : {
19488
+ // Slice before projecting `._id`: `..._id[0...n]` binds the slice to the
19489
+ // `_id` string and yields `null` per element; `...[0...n]._id` is correct.
19490
+ query: `*[${Array.from(new Set(specs.map((spec) => {
19491
+ const matchTarget = spec.mapWith ? `${spec.mapWith}(${spec.leafPath})` : spec.leafPath;
19492
+ return `(_type == "${spec.targetType}" && ${matchTarget} match text::query($__query))`;
19493
+ }))).join(" || ")}][0...${REFERENCE_RESOLVE_LIMIT}]._id`,
19494
+ params: {
19495
+ __query: prefixLast(rawQuery)
19496
+ }
19497
+ };
19498
+ }
19395
19499
  function getSortTarget(ordering) {
19396
19500
  return ordering.projectionIndex === void 0 ? ordering.field : `${ORDERINGS_PROJECTION_KEY}[${ordering.projectionIndex}]`;
19397
19501
  }
@@ -19431,8 +19535,11 @@ function createSearchQuery$1(searchTerms, searchParams, {
19431
19535
  params,
19432
19536
  comments: comments2,
19433
19537
  filter: filter2
19538
+ } = {}, {
19539
+ referenceIds,
19540
+ referenceWeight = 5
19434
19541
  } = {}) {
19435
- const flattenedSpecs = searchTerms.types.map((schemaType) => deriveSearchWeightsFromType2024({
19542
+ const hasReferenceIds = Array.isArray(referenceIds) && referenceIds.length > 0, flattenedSpecs = searchTerms.types.map((schemaType) => deriveSearchWeightsFromType2024({
19436
19543
  schemaType,
19437
19544
  maxDepth: maxDepth || DEFAULT_MAX_FIELD_DEPTH,
19438
19545
  isCrossDataset,
@@ -19447,9 +19554,9 @@ function createSearchQuery$1(searchTerms, searchParams, {
19447
19554
  }) => paths.map((path) => ({
19448
19555
  ...path,
19449
19556
  typeName
19450
- }))), groupedSpecs = groupBy(flattenedSpecs, (entry) => [entry.path, entry.weight].join(":")), baseMatch = "([@, _id] match text::query($__query) || references($__rawQuery))", score = Object.entries(groupedSpecs).flatMap(([, entries]) => entries.some(({
19557
+ }))), groupedSpecs = groupBy(flattenedSpecs, (entry) => [entry.path, entry.weight].join(":")), baseMatch = "([@, _id] match text::query($__query) || references($__rawQuery))", referenceBoost = hasReferenceIds ? [`boost(references($__refIds), ${referenceWeight})`] : [], score = Object.entries(groupedSpecs).flatMap(([, entries]) => entries.some(({
19451
19558
  weight
19452
- }) => weight === 0) ? [] : `boost(_type in ${JSON.stringify(entries.map((entry) => entry.typeName))} && ${entries[0].path} match text::query($__query), ${entries[0].weight})`).concat(baseMatch), inputSortOrder = sort ?? [{
19559
+ }) => weight === 0) ? [] : `boost(_type in ${JSON.stringify(entries.map((entry) => entry.typeName))} && ${entries[0].path} match text::query($__query), ${entries[0].weight})`).concat(referenceBoost).concat(baseMatch), inputSortOrder = sort ?? [{
19453
19560
  field: "_score",
19454
19561
  direction: "desc"
19455
19562
  }], isScored = inputSortOrder.some(({
@@ -19457,10 +19564,10 @@ function createSearchQuery$1(searchTerms, searchParams, {
19457
19564
  }) => field === "_score"), compiledSortEntries = inputSortOrder.map((entry, index) => compileSortExpression(entry, index)), sortOrder = inputSortOrder.map((entry, index) => ({
19458
19565
  ...entry,
19459
19566
  projectionIndex: compiledSortEntries[index].projectionIndex
19460
- })), filters = [
19567
+ })), unscoredMatch = hasReferenceIds ? `(${baseMatch} || references($__refIds))` : baseMatch, filters = [
19461
19568
  "_type in $__types",
19462
19569
  // If the search request doesn't use scoring, directly filter documents.
19463
- isScored ? [] : baseMatch,
19570
+ isScored ? [] : unscoredMatch,
19464
19571
  filter2 ? `(${filter2})` : [],
19465
19572
  searchTerms.filter ? `(${searchTerms.filter})` : [],
19466
19573
  cursor ?? []
@@ -19470,6 +19577,9 @@ function createSearchQuery$1(searchTerms, searchParams, {
19470
19577
  __limit: (limit2 ?? DEFAULT_LIMIT$1) + 1,
19471
19578
  __query: prefixLast(rawQuery),
19472
19579
  __rawQuery: rawQuery,
19580
+ ...hasReferenceIds ? {
19581
+ __refIds: referenceIds
19582
+ } : {},
19473
19583
  ...params
19474
19584
  };
19475
19585
  return {
@@ -19535,29 +19645,50 @@ const createGroq2024Search = (typesFromFactory, client, factoryOptions) => funct
19535
19645
  const searchTerms = getSearchTerms$1(searchParams, typesFromFactory), mergedOptions = {
19536
19646
  ...factoryOptions,
19537
19647
  ...searchOptions
19538
- }, {
19539
- query,
19540
- params,
19541
- options,
19542
- sortOrder,
19543
- compiledSortEntries
19544
- } = createSearchQuery$1(searchTerms, searchParams, mergedOptions);
19545
- return client.observable.fetch(query, params, options).pipe(map$1((hits) => {
19546
- const hasNextPage = typeof searchOptions.limit < "u" && hits.length > searchOptions.limit, lastResult = hasNextPage ? hits.at(-2) : hits.at(-1);
19547
- return {
19548
- type: "groq2024",
19549
- // Search overfetches by 1 to determine whether there is another page to fetch. Therefore,
19550
- // exclude the final result if it's beyond the limit.
19551
- hits: hits.map((hit) => ({
19552
- hit
19553
- })).slice(0, searchOptions.limit),
19554
- nextCursor: hasNextPage ? getNextCursor({
19555
- lastResult,
19556
- sortOrder,
19557
- compiledSortEntries
19558
- }) : void 0
19559
- };
19560
- }));
19648
+ }, rawQuery = typeof searchParams == "string" ? searchParams : searchParams.query, referenceSpecs = searchTerms.types.flatMap((schemaType) => deriveReferenceSearchSpecs({
19649
+ schemaType,
19650
+ maxDepth: mergedOptions.maxDepth || DEFAULT_MAX_FIELD_DEPTH
19651
+ })), maxReferenceWeight = referenceSpecs.reduce((highest, spec) => Math.max(highest, spec.weight), 0), runMainSearch = (referenceIds) => {
19652
+ const {
19653
+ query,
19654
+ params,
19655
+ options,
19656
+ sortOrder,
19657
+ compiledSortEntries
19658
+ } = createSearchQuery$1(searchTerms, searchParams, mergedOptions, {
19659
+ referenceIds,
19660
+ referenceWeight: maxReferenceWeight
19661
+ });
19662
+ return client.observable.fetch(query, params, options).pipe(map$1((hits) => {
19663
+ const hasNextPage = typeof searchOptions.limit < "u" && hits.length > searchOptions.limit, lastResult = hasNextPage ? hits.at(-2) : hits.at(-1);
19664
+ return {
19665
+ type: "groq2024",
19666
+ // Search overfetches by 1 to detect a next page. Slice to the effective
19667
+ // limit - falling back to `__limit - 1` when no limit was passed - so the
19668
+ // overfetched element never leaks.
19669
+ hits: hits.map((hit) => ({
19670
+ hit
19671
+ })).slice(0, searchOptions.limit ?? params.__limit - 1),
19672
+ nextCursor: hasNextPage ? getNextCursor({
19673
+ lastResult,
19674
+ sortOrder,
19675
+ compiledSortEntries
19676
+ }) : void 0
19677
+ };
19678
+ }));
19679
+ }, resolveQuery = rawQuery ? createReferenceResolveQuery(referenceSpecs, rawQuery) : void 0;
19680
+ return resolveQuery === void 0 ? runMainSearch() : client.observable.fetch(resolveQuery.query, resolveQuery.params, {
19681
+ tag: mergedOptions.tag,
19682
+ perspective: mergedOptions.perspective
19683
+ }).pipe(
19684
+ // Reference resolution is an enhancement: if phase one fails, fall back
19685
+ // to a plain search rather than failing the base term-match too.
19686
+ catchError$1(() => of([])),
19687
+ mergeMap$1((resolvedIds) => {
19688
+ const publishedIds = Array.from(new Set((resolvedIds ?? []).filter((resolvedId) => typeof resolvedId == "string").map((resolvedId) => getPublishedId(resolvedId))));
19689
+ return runMainSearch(publishedIds.length > 0 ? publishedIds : void 0);
19690
+ })
19691
+ );
19561
19692
  }, calculateScore = (searchTerms, value) => {
19562
19693
  const {
19563
19694
  phrases: uniqueSearchPhrases,
@@ -42894,7 +43025,7 @@ function defaultResolveInputComponent(schemaType) {
42894
43025
  const componentFromTypeVariants = resolveComponentFromTypeVariants(schemaType);
42895
43026
  if (componentFromTypeVariants)
42896
43027
  return componentFromTypeVariants;
42897
- const deduped = getTypeChain$2(schemaType, /* @__PURE__ */ new Set()).reduce((acc, type) => (acc[type.name] = type, acc), {}), subType = Object.values(deduped).find((t) => defaultInputs[t.name]);
43028
+ const deduped = getTypeChain$3(schemaType, /* @__PURE__ */ new Set()).reduce((acc, type) => (acc[type.name] = type, acc), {}), subType = Object.values(deduped).find((t) => defaultInputs[t.name]);
42898
43029
  if (subType)
42899
43030
  return defaultInputs[subType.name];
42900
43031
  throw new Error(`Could not find input component for schema type \`${schemaType.name}\``);