@sanity/assist 4.4.5 → 4.4.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/dist/index.d.mts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.esm.js +300 -259
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +298 -257
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +300 -259
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/assistDocument/AssistDocumentContext.tsx +1 -3
- package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +7 -17
- package/src/assistInspector/FieldAutocomplete.tsx +9 -4
- package/src/assistInspector/helpers.ts +15 -26
- package/src/assistLayout/AiAssistanceConfigContext.tsx +9 -59
- package/src/assistLayout/AiAssistanceConfigProvider.tsx +98 -0
- package/src/assistLayout/AssistLayout.tsx +1 -1
- package/src/assistLayout/fieldRefCache.tsx +34 -0
- package/src/fieldActions/customFieldActions.tsx +2 -1
- package/src/schemas/assistDocumentSchema.tsx +9 -6
- package/src/schemas/typeDefExtensions.ts +1 -0
- package/src/useApiClient.ts +1 -2
package/dist/index.js
CHANGED
|
@@ -385,99 +385,6 @@ function useAssistDocumentContext() {
|
|
|
385
385
|
throw new Error("AssistDocumentContext value is missing");
|
|
386
386
|
return context;
|
|
387
387
|
}
|
|
388
|
-
const SelectedFieldContext = react.createContext(void 0), SelectedFieldContextProvider = SelectedFieldContext.Provider, maxDepth = 6;
|
|
389
|
-
function getTypeIcon(schemaType) {
|
|
390
|
-
let t = schemaType;
|
|
391
|
-
for (; t; ) {
|
|
392
|
-
if (t.icon) return t.icon;
|
|
393
|
-
t = t.type;
|
|
394
|
-
}
|
|
395
|
-
return isType(schemaType, "slug") ? icons.LinkIcon : isType(schemaType, "image") ? icons.ImageIcon : schemaType.jsonType === "array" && isPortableTextArray(schemaType) ? icons.BlockContentIcon : schemaType.jsonType === "array" ? icons.OlistIcon : schemaType.jsonType === "object" ? icons.BlockquoteIcon : schemaType.jsonType === "string" ? icons.StringIcon : icons.DocumentIcon;
|
|
396
|
-
}
|
|
397
|
-
function asFieldRefsByTypePath(fieldRefs) {
|
|
398
|
-
return fieldRefs.reduce(
|
|
399
|
-
(acc, ref) => ({ ...acc, [ref.key]: ref }),
|
|
400
|
-
{}
|
|
401
|
-
);
|
|
402
|
-
}
|
|
403
|
-
function getFieldRefsWithDocument(schemaType) {
|
|
404
|
-
const fields = getFieldRefs(schemaType);
|
|
405
|
-
return [
|
|
406
|
-
{
|
|
407
|
-
key: documentRootKey,
|
|
408
|
-
icon: schemaType.icon ?? icons.DocumentIcon,
|
|
409
|
-
title: "The entire document",
|
|
410
|
-
path: [],
|
|
411
|
-
schemaType
|
|
412
|
-
},
|
|
413
|
-
...fields
|
|
414
|
-
];
|
|
415
|
-
}
|
|
416
|
-
function getFieldRefs(schemaType, parent, depth = 0) {
|
|
417
|
-
return depth >= maxDepth ? [] : schemaType.fields.filter((f) => !f.name.startsWith("_")).flatMap((field) => {
|
|
418
|
-
const path = parent ? [...parent.path, field.name] : [field.name], title = field.type.title ?? field.name, fieldRef = {
|
|
419
|
-
key: patchableKey(sanity.pathToString(path)),
|
|
420
|
-
path,
|
|
421
|
-
title: parent ? [parent.title, title].join(" / ") : title,
|
|
422
|
-
schemaType: field.type,
|
|
423
|
-
icon: getTypeIcon(field.type)
|
|
424
|
-
}, fields = field.type.jsonType === "object" ? getFieldRefs(field.type, fieldRef, depth + 1) : [], syntheticFields = field.type.jsonType === "array" ? getSyntheticFields(field.type, fieldRef, depth + 1) : [];
|
|
425
|
-
return isAssistSupported(field.type) ? [fieldRef, ...fields, ...syntheticFields] : [...fields, ...syntheticFields];
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
function getSyntheticFields(schemaType, parent, depth = 0) {
|
|
429
|
-
return depth >= maxDepth ? [] : schemaType.of.filter((itemType) => !isType(itemType, "block")).flatMap((itemType) => {
|
|
430
|
-
const segment = { _key: itemType.name }, title = itemType.title ?? itemType.name, path = parent ? [...parent.path, segment] : [segment], fieldRef = {
|
|
431
|
-
key: patchableKey(sanity.pathToString(path)),
|
|
432
|
-
path,
|
|
433
|
-
title: parent ? [parent.title, title].join(" / ") : title,
|
|
434
|
-
schemaType: itemType,
|
|
435
|
-
icon: getTypeIcon(itemType),
|
|
436
|
-
synthetic: !0
|
|
437
|
-
}, fields = itemType.jsonType === "object" ? getFieldRefs(itemType, fieldRef, depth + 1) : [];
|
|
438
|
-
return isAssistSupported(itemType) ? [fieldRef, ...fields] : fields;
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
function getTypePath(doc, pathString) {
|
|
442
|
-
if (!pathString)
|
|
443
|
-
return;
|
|
444
|
-
const path = sanity.stringToPath(pathString), currentPath = [];
|
|
445
|
-
let valid = !0;
|
|
446
|
-
const syntheticPath = path.map((segment) => {
|
|
447
|
-
if (currentPath.push(segment), sanity.isKeySegment(segment)) {
|
|
448
|
-
const match = mutator.extractWithPath(sanity.pathToString(currentPath), doc)[0], value = match?.value;
|
|
449
|
-
if (match && value && typeof value == "object" && "_type" in value)
|
|
450
|
-
return { _key: value._type };
|
|
451
|
-
valid = !1;
|
|
452
|
-
}
|
|
453
|
-
return segment;
|
|
454
|
-
});
|
|
455
|
-
return valid ? patchableKey(sanity.pathToString(syntheticPath)) : void 0;
|
|
456
|
-
}
|
|
457
|
-
function patchableKey(pathKey) {
|
|
458
|
-
return pathKey.replace(/[=]=/g, ":").replace(/[[\]]/g, "|").replace(/"/g, "");
|
|
459
|
-
}
|
|
460
|
-
function useTypePath(doc, pathString) {
|
|
461
|
-
return react.useMemo(() => getTypePath(doc, pathString), [doc, pathString]);
|
|
462
|
-
}
|
|
463
|
-
function useSelectedField(documentSchemaType, path) {
|
|
464
|
-
const selectableFields = react.useMemo(
|
|
465
|
-
() => documentSchemaType && sanity.isObjectSchemaType(documentSchemaType) ? getFieldRefsWithDocument(documentSchemaType) : [],
|
|
466
|
-
[documentSchemaType]
|
|
467
|
-
);
|
|
468
|
-
return react.useMemo(() => path ? selectableFields?.find((f) => f.key === path) : void 0, [selectableFields, path]);
|
|
469
|
-
}
|
|
470
|
-
function getFieldTitle(field) {
|
|
471
|
-
const schemaType = field?.schemaType;
|
|
472
|
-
return field?.title ?? schemaType?.title ?? schemaType?.name ?? "Untitled";
|
|
473
|
-
}
|
|
474
|
-
function useAiPaneRouter() {
|
|
475
|
-
const paneRouter = structure.usePaneRouter();
|
|
476
|
-
return react.useMemo(
|
|
477
|
-
() => ({ ...paneRouter, params: paneRouter.params ?? {} }),
|
|
478
|
-
[paneRouter]
|
|
479
|
-
);
|
|
480
|
-
}
|
|
481
388
|
const AiAssistanceConfigContext = react.createContext({});
|
|
482
389
|
function useAiAssistanceConfig() {
|
|
483
390
|
const context = react.useContext(AiAssistanceConfigContext);
|
|
@@ -485,31 +392,8 @@ function useAiAssistanceConfig() {
|
|
|
485
392
|
throw new Error("Missing AiAssistanceConfigContext");
|
|
486
393
|
return context;
|
|
487
394
|
}
|
|
488
|
-
function
|
|
489
|
-
|
|
490
|
-
react.useEffect(() => {
|
|
491
|
-
getInstructStatus().then((s) => setStatus(s)).catch((e) => {
|
|
492
|
-
console.error(e), setError(e);
|
|
493
|
-
});
|
|
494
|
-
}, [getInstructStatus]);
|
|
495
|
-
const init = react.useCallback(async () => {
|
|
496
|
-
setError(void 0);
|
|
497
|
-
try {
|
|
498
|
-
await initInstruct();
|
|
499
|
-
const status2 = await getInstructStatus();
|
|
500
|
-
setStatus(status2);
|
|
501
|
-
} catch (e) {
|
|
502
|
-
console.error("Failed to init ai assistance", e), setError(e);
|
|
503
|
-
}
|
|
504
|
-
}, [initInstruct, getInstructStatus, setStatus]), { config, children } = props, context = react.useMemo(() => ({
|
|
505
|
-
config,
|
|
506
|
-
status,
|
|
507
|
-
statusLoading,
|
|
508
|
-
init,
|
|
509
|
-
initLoading,
|
|
510
|
-
error
|
|
511
|
-
}), [config, status, init, statusLoading, initLoading, error]);
|
|
512
|
-
return /* @__PURE__ */ jsxRuntime.jsx(AiAssistanceConfigContext.Provider, { value: context, children });
|
|
395
|
+
function useSerializedTypes() {
|
|
396
|
+
return useAiAssistanceConfig().serializedTypes;
|
|
513
397
|
}
|
|
514
398
|
const basePath = "/assist/tasks/instruction", API_VERSION_WITH_EXTENDED_TYPES = "2025-04-01";
|
|
515
399
|
function canUseAssist(status) {
|
|
@@ -889,144 +773,105 @@ function useDraftDelayedTask(args) {
|
|
|
889
773
|
[setQueuedArgs, documentOnChange]
|
|
890
774
|
);
|
|
891
775
|
}
|
|
892
|
-
const
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
"
|
|
900
|
-
"document",
|
|
901
|
-
"email",
|
|
902
|
-
"file",
|
|
903
|
-
"globalDocumentReference",
|
|
904
|
-
"image",
|
|
905
|
-
"number",
|
|
906
|
-
"object",
|
|
907
|
-
"reference",
|
|
908
|
-
"span",
|
|
909
|
-
"string",
|
|
910
|
-
"text",
|
|
911
|
-
"url",
|
|
912
|
-
"slug",
|
|
913
|
-
"geopoint",
|
|
914
|
-
"sanity.assetSourceData",
|
|
915
|
-
"sanity.imageAsset",
|
|
916
|
-
"sanity.fileAsset",
|
|
917
|
-
"sanity.imageCrop",
|
|
918
|
-
"sanity.imageHotspot",
|
|
919
|
-
"sanity.imageMetadata",
|
|
920
|
-
"sanity.imageDimensions",
|
|
921
|
-
"sanity.imagePalette",
|
|
922
|
-
"sanity.imagePaletteSwatch",
|
|
923
|
-
assistSerializedTypeName,
|
|
924
|
-
assistSerializedFieldTypeName,
|
|
925
|
-
"sanity-agent.job.document"
|
|
926
|
-
], inlineTypes = ["document", "object", "image", "file"];
|
|
927
|
-
function serializeSchema(schema, options2) {
|
|
928
|
-
const list = schema.getTypeNames().filter((t) => !(hiddenTypes.includes(t) || t.startsWith("sanity."))).map((t) => schema.get(t)).filter((t) => !!t).map((t) => getSchemaStub(t, schema, options2)).filter((t) => !("to" in t && t.to && !t.to.length || "of" in t && t.of && !t.of.length || "fields" in t && t.fields && !t.fields.length));
|
|
929
|
-
return list.sort((a, b) => (a?.name ?? "").localeCompare(b?.name ?? "")), list;
|
|
776
|
+
const maxDepth = 6;
|
|
777
|
+
function getTypeIcon(schemaType) {
|
|
778
|
+
let t = schemaType;
|
|
779
|
+
for (; t; ) {
|
|
780
|
+
if (t.icon) return t.icon;
|
|
781
|
+
t = t.type;
|
|
782
|
+
}
|
|
783
|
+
return isType(schemaType, "slug") ? icons.LinkIcon : isType(schemaType, "image") ? icons.ImageIcon : schemaType.jsonType === "array" && isPortableTextArray(schemaType) ? icons.BlockContentIcon : schemaType.jsonType === "array" ? icons.OlistIcon : schemaType.jsonType === "object" ? icons.BlockquoteIcon : schemaType.jsonType === "string" ? icons.StringIcon : icons.DocumentIcon;
|
|
930
784
|
}
|
|
931
|
-
function
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
785
|
+
function asFieldRefsByTypePath(fieldRefs) {
|
|
786
|
+
return fieldRefs.reduce(
|
|
787
|
+
(acc, ref) => ({ ...acc, [ref.key]: ref }),
|
|
788
|
+
{}
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
function getDocumentFieldRef(schemaType) {
|
|
792
|
+
return {
|
|
793
|
+
key: documentRootKey,
|
|
794
|
+
icon: schemaType.icon ?? icons.DocumentIcon,
|
|
795
|
+
title: "The entire document",
|
|
796
|
+
path: [],
|
|
797
|
+
schemaType
|
|
941
798
|
};
|
|
942
|
-
return removeUndef(baseSchema);
|
|
943
799
|
}
|
|
944
|
-
function
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
) :
|
|
954
|
-
of: "of" in type && typeName === "array" ? arrayOf(type, schema, options2) : void 0,
|
|
955
|
-
to: "to" in type && typeName === "reference" ? refToTypeNames(type) : void 0,
|
|
956
|
-
fields: "fields" in type && inlineTypes.includes(typeName) ? serializeFields(schema, type, options2) : void 0,
|
|
957
|
-
annotations: typeName === "block" && "fields" in type ? serializeAnnotations(type, schema, options2) : void 0,
|
|
958
|
-
inlineOf: typeName === "block" && "fields" in type ? serializeInlineOf(type, schema, options2) : void 0,
|
|
959
|
-
hidden: typeof type.hidden == "function" ? "function" : type.hidden ? !0 : void 0,
|
|
960
|
-
readOnly: typeof type.readOnly == "function" ? "function" : type.readOnly ? !0 : void 0
|
|
800
|
+
function getFieldRefs(schemaType, parent, depth = 0) {
|
|
801
|
+
return depth >= maxDepth ? [] : schemaType.fields.filter((f) => !f.name.startsWith("_")).flatMap((field) => {
|
|
802
|
+
const path = parent ? [...parent.path, field.name] : [field.name], title = field.type.title ?? field.name, fieldRef = {
|
|
803
|
+
key: patchableKey(sanity.pathToString(path)),
|
|
804
|
+
path,
|
|
805
|
+
title: parent ? [parent.title, title].join(" / ") : title,
|
|
806
|
+
schemaType: field.type,
|
|
807
|
+
icon: getTypeIcon(field.type)
|
|
808
|
+
}, fields = field.type.jsonType === "object" ? getFieldRefs(field.type, fieldRef, depth + 1) : [], syntheticFields = field.type.jsonType === "array" ? getSyntheticFields(field.type, fieldRef, depth + 1) : [];
|
|
809
|
+
return isAssistSupported(field.type) ? [fieldRef, ...fields, ...syntheticFields] : [...fields, ...syntheticFields];
|
|
961
810
|
});
|
|
962
811
|
}
|
|
963
|
-
function
|
|
964
|
-
return
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
}))
|
|
975
|
-
) : schemaType.fields).filter((f) => !["sanity.imageHotspot", "sanity.imageCrop"].includes(f.type?.name ?? "")).filter((f) => isAssistSupported(f.type)).map((field) => serializeMember(schema, field.type, field.name, options2));
|
|
976
|
-
}
|
|
977
|
-
function serializeMember(schema, type, name, options2) {
|
|
978
|
-
const typeName = schema.get(type?.name) ? type.name : type.type?.name ?? "";
|
|
979
|
-
return removeUndef({
|
|
980
|
-
...options2?.leanFormat ? {} : { _type: assistSerializedFieldTypeName },
|
|
981
|
-
name,
|
|
982
|
-
type: typeName,
|
|
983
|
-
title: type.title,
|
|
984
|
-
...getBaseFields(schema, type, typeName, options2)
|
|
812
|
+
function getSyntheticFields(schemaType, parent, depth = 0) {
|
|
813
|
+
return depth >= maxDepth ? [] : schemaType.of.filter((itemType) => !isType(itemType, "block")).flatMap((itemType) => {
|
|
814
|
+
const segment = { _key: itemType.name }, title = itemType.title ?? itemType.name, path = parent ? [...parent.path, segment] : [segment], fieldRef = {
|
|
815
|
+
key: patchableKey(sanity.pathToString(path)),
|
|
816
|
+
path,
|
|
817
|
+
title: parent ? [parent.title, title].join(" / ") : title,
|
|
818
|
+
schemaType: itemType,
|
|
819
|
+
icon: getTypeIcon(itemType),
|
|
820
|
+
synthetic: !0
|
|
821
|
+
}, fields = itemType.jsonType === "object" ? getFieldRefs(itemType, fieldRef, depth + 1) : [];
|
|
822
|
+
return isAssistSupported(itemType) ? [fieldRef, ...fields] : fields;
|
|
985
823
|
});
|
|
986
824
|
}
|
|
987
|
-
function
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
825
|
+
function getTypePath(doc, pathString) {
|
|
826
|
+
if (!pathString)
|
|
827
|
+
return;
|
|
828
|
+
const path = sanity.stringToPath(pathString), currentPath = [];
|
|
829
|
+
let valid = !0;
|
|
830
|
+
const syntheticPath = path.map((segment) => {
|
|
831
|
+
if (currentPath.push(segment), sanity.isKeySegment(segment)) {
|
|
832
|
+
const match = mutator.extractWithPath(sanity.pathToString(currentPath), doc)[0], value = match?.value;
|
|
833
|
+
if (match && value && typeof value == "object" && "_type" in value)
|
|
834
|
+
return { _key: value._type };
|
|
835
|
+
valid = !1;
|
|
836
|
+
}
|
|
837
|
+
return segment;
|
|
838
|
+
});
|
|
839
|
+
return valid ? patchableKey(sanity.pathToString(syntheticPath)) : void 0;
|
|
997
840
|
}
|
|
998
|
-
function
|
|
999
|
-
|
|
1000
|
-
if (!(!marksType || !sanity.isArraySchemaType(marksType)))
|
|
1001
|
-
return arrayOf(marksType, schema, options2);
|
|
841
|
+
function patchableKey(pathKey) {
|
|
842
|
+
return pathKey.replace(/[=]=/g, ":").replace(/[[\]]/g, "|").replace(/"/g, "");
|
|
1002
843
|
}
|
|
1003
|
-
function
|
|
1004
|
-
return
|
|
844
|
+
function useTypePath(doc, pathString) {
|
|
845
|
+
return react.useMemo(() => getTypePath(doc, pathString), [doc, pathString]);
|
|
1005
846
|
}
|
|
1006
|
-
function
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
847
|
+
function useSelectedField(documentSchemaType, path) {
|
|
848
|
+
const { getFieldRefs: getFieldRefs2 } = useAiAssistanceConfig(), selectableFields = react.useMemo(
|
|
849
|
+
() => documentSchemaType && sanity.isObjectSchemaType(documentSchemaType) ? [getDocumentFieldRef(documentSchemaType), ...getFieldRefs2(documentSchemaType.name)] : [],
|
|
850
|
+
[documentSchemaType, getFieldRefs2]
|
|
851
|
+
);
|
|
852
|
+
return react.useMemo(() => path ? selectableFields?.find((f) => f.key === path) : void 0, [selectableFields, path]);
|
|
1010
853
|
}
|
|
1011
|
-
function
|
|
1012
|
-
|
|
854
|
+
function getFieldTitle(field) {
|
|
855
|
+
const schemaType = field?.schemaType;
|
|
856
|
+
return field?.title ?? schemaType?.title ?? schemaType?.name ?? "Untitled";
|
|
1013
857
|
}
|
|
1014
|
-
function
|
|
1015
|
-
|
|
858
|
+
function useAiPaneRouter() {
|
|
859
|
+
const paneRouter = structure.usePaneRouter();
|
|
860
|
+
return react.useMemo(
|
|
861
|
+
() => ({ ...paneRouter, params: paneRouter.params ?? {} }),
|
|
862
|
+
[paneRouter]
|
|
863
|
+
);
|
|
1016
864
|
}
|
|
1017
865
|
function useAssistDocumentContextValue(documentId, documentType) {
|
|
1018
|
-
const schema = sanity.useSchema(), documentSchemaType = react.useMemo(() => {
|
|
866
|
+
const schema = sanity.useSchema(), { getFieldRefs: getFieldRefs2, getFieldRefsByTypePath } = useAiAssistanceConfig(), documentSchemaType = react.useMemo(() => {
|
|
1019
867
|
const schemaType = schema.get(documentType);
|
|
1020
868
|
if (!schemaType)
|
|
1021
869
|
throw new Error(`Schema type "${documentType}" not found`);
|
|
1022
870
|
return schemaType;
|
|
1023
|
-
}, [documentType, schema]),
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
fieldRefsByTypePath: fieldRefsByTypePath2
|
|
1028
|
-
};
|
|
1029
|
-
}, [documentSchemaType]), {
|
|
871
|
+
}, [documentType, schema]), { fieldRefs, fieldRefsByTypePath } = react.useMemo(() => ({
|
|
872
|
+
fieldRefs: getFieldRefs2(documentType),
|
|
873
|
+
fieldRefsByTypePath: getFieldRefsByTypePath(documentType)
|
|
874
|
+
}), [getFieldRefs2, getFieldRefsByTypePath, documentType]), {
|
|
1030
875
|
openInspector,
|
|
1031
876
|
closeInspector,
|
|
1032
877
|
inspector,
|
|
@@ -1054,8 +899,7 @@ function useAssistDocumentContextValue(documentId, documentType) {
|
|
|
1054
899
|
addSyntheticTask,
|
|
1055
900
|
removeSyntheticTask,
|
|
1056
901
|
fieldRefs,
|
|
1057
|
-
fieldRefsByTypePath
|
|
1058
|
-
serializedTypes
|
|
902
|
+
fieldRefsByTypePath
|
|
1059
903
|
};
|
|
1060
904
|
return assistDocument ? {
|
|
1061
905
|
...base,
|
|
@@ -1077,8 +921,7 @@ function useAssistDocumentContextValue(documentId, documentType) {
|
|
|
1077
921
|
addSyntheticTask,
|
|
1078
922
|
removeSyntheticTask,
|
|
1079
923
|
fieldRefs,
|
|
1080
|
-
fieldRefsByTypePath
|
|
1081
|
-
serializedTypes
|
|
924
|
+
fieldRefsByTypePath
|
|
1082
925
|
]);
|
|
1083
926
|
}
|
|
1084
927
|
function useSyntheticTasks(assistableDocumentId) {
|
|
@@ -1595,7 +1438,10 @@ function InspectorOnboarding(props) {
|
|
|
1595
1438
|
] }) }) });
|
|
1596
1439
|
}
|
|
1597
1440
|
function FieldAutocomplete(props) {
|
|
1598
|
-
const { id, schemaType, fieldPath, onSelect, includeDocument, filter } = props,
|
|
1441
|
+
const { id, schemaType, fieldPath, onSelect, includeDocument, filter } = props, { getFieldRefs: getFieldRefs2 } = useAiAssistanceConfig(), fieldRefs = react.useMemo(() => {
|
|
1442
|
+
const refs = getFieldRefs2(schemaType.name);
|
|
1443
|
+
return includeDocument ? [getDocumentFieldRef(schemaType), ...refs] : refs;
|
|
1444
|
+
}, [schemaType, includeDocument, getFieldRefs2]), currentField = react.useMemo(
|
|
1599
1445
|
() => fieldRefs.find((f) => f.key === fieldPath),
|
|
1600
1446
|
[fieldPath, fieldRefs]
|
|
1601
1447
|
), autocompleteOptions = react.useMemo(
|
|
@@ -2596,6 +2442,195 @@ function FromLanguageRadio(props) {
|
|
|
2596
2442
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: radioLanguage.title ?? radioLanguage.id })
|
|
2597
2443
|
] }, langId);
|
|
2598
2444
|
}
|
|
2445
|
+
const hiddenTypes = [
|
|
2446
|
+
"any",
|
|
2447
|
+
"array",
|
|
2448
|
+
"block",
|
|
2449
|
+
"boolean",
|
|
2450
|
+
"crossDatasetReference",
|
|
2451
|
+
"date",
|
|
2452
|
+
"datetime",
|
|
2453
|
+
"document",
|
|
2454
|
+
"email",
|
|
2455
|
+
"file",
|
|
2456
|
+
"globalDocumentReference",
|
|
2457
|
+
"image",
|
|
2458
|
+
"number",
|
|
2459
|
+
"object",
|
|
2460
|
+
"reference",
|
|
2461
|
+
"span",
|
|
2462
|
+
"string",
|
|
2463
|
+
"text",
|
|
2464
|
+
"url",
|
|
2465
|
+
"slug",
|
|
2466
|
+
"geopoint",
|
|
2467
|
+
"sanity.assetSourceData",
|
|
2468
|
+
"sanity.imageAsset",
|
|
2469
|
+
"sanity.fileAsset",
|
|
2470
|
+
"sanity.imageCrop",
|
|
2471
|
+
"sanity.imageHotspot",
|
|
2472
|
+
"sanity.imageMetadata",
|
|
2473
|
+
"sanity.imageDimensions",
|
|
2474
|
+
"sanity.imagePalette",
|
|
2475
|
+
"sanity.imagePaletteSwatch",
|
|
2476
|
+
assistSerializedTypeName,
|
|
2477
|
+
assistSerializedFieldTypeName,
|
|
2478
|
+
"sanity-agent.job.document"
|
|
2479
|
+
], inlineTypes = ["document", "object", "image", "file"];
|
|
2480
|
+
function serializeSchema(schema, options2) {
|
|
2481
|
+
const list = schema.getTypeNames().filter((t) => !(hiddenTypes.includes(t) || t.startsWith("sanity."))).map((t) => schema.get(t)).filter((t) => !!t).map((t) => getSchemaStub(t, schema, options2)).filter((t) => !("to" in t && t.to && !t.to.length || "of" in t && t.of && !t.of.length || "fields" in t && t.fields && !t.fields.length));
|
|
2482
|
+
return list.sort((a, b) => (a?.name ?? "").localeCompare(b?.name ?? "")), list;
|
|
2483
|
+
}
|
|
2484
|
+
function getSchemaStub(schemaType, schema, options2) {
|
|
2485
|
+
if (!schemaType.type?.name)
|
|
2486
|
+
throw console.error("Missing type name", schemaType.type), new Error("Type is missing name!");
|
|
2487
|
+
const baseSchema = {
|
|
2488
|
+
// we dont need type or id when we send using POST, so leave these out to save bandwidth
|
|
2489
|
+
...options2?.leanFormat ? {} : { _id: `${assistSchemaIdPrefix}${schemaType.name}`, _type: assistSerializedTypeName },
|
|
2490
|
+
name: schemaType.name,
|
|
2491
|
+
title: schemaType.title,
|
|
2492
|
+
type: schemaType.type.name,
|
|
2493
|
+
...getBaseFields(schema, schemaType, schemaType.type.name, options2)
|
|
2494
|
+
};
|
|
2495
|
+
return removeUndef(baseSchema);
|
|
2496
|
+
}
|
|
2497
|
+
function getBaseFields(schema, type, typeName, options2) {
|
|
2498
|
+
const schemaOptions = removeUndef({
|
|
2499
|
+
imagePromptField: type.options?.aiAssist?.imageInstructionField,
|
|
2500
|
+
embeddingsIndex: type.options?.aiAssist?.embeddingsIndex
|
|
2501
|
+
});
|
|
2502
|
+
return removeUndef({
|
|
2503
|
+
options: Object.keys(schemaOptions).length ? schemaOptions : void 0,
|
|
2504
|
+
values: Array.isArray(type?.options?.list) ? type?.options?.list.map(
|
|
2505
|
+
(v) => typeof v == "string" ? v : v.value ?? `${v.title}`
|
|
2506
|
+
) : void 0,
|
|
2507
|
+
of: "of" in type && typeName === "array" ? arrayOf(type, schema, options2) : void 0,
|
|
2508
|
+
to: "to" in type && typeName === "reference" ? refToTypeNames(type) : void 0,
|
|
2509
|
+
fields: "fields" in type && inlineTypes.includes(typeName) ? serializeFields(schema, type, options2) : void 0,
|
|
2510
|
+
annotations: typeName === "block" && "fields" in type ? serializeAnnotations(type, schema, options2) : void 0,
|
|
2511
|
+
inlineOf: typeName === "block" && "fields" in type ? serializeInlineOf(type, schema, options2) : void 0,
|
|
2512
|
+
hidden: typeof type.hidden == "function" ? "function" : type.hidden ? !0 : void 0,
|
|
2513
|
+
readOnly: typeof type.readOnly == "function" ? "function" : type.readOnly ? !0 : void 0
|
|
2514
|
+
});
|
|
2515
|
+
}
|
|
2516
|
+
function serializeFields(schema, schemaType, options2) {
|
|
2517
|
+
return (schemaType.fieldsets ? schemaType.fieldsets.flatMap(
|
|
2518
|
+
(fs) => fs.single ? fs.field : fs.fields.map((f) => ({
|
|
2519
|
+
...f,
|
|
2520
|
+
type: {
|
|
2521
|
+
...f.type,
|
|
2522
|
+
// if fieldset is (conditionally) hidden, the field must be considered the same way
|
|
2523
|
+
// ie, if the field does not show up in conditionalMembers, it is hidden
|
|
2524
|
+
// regardless of weather or not it is the field function or the fieldset function that hides it
|
|
2525
|
+
hidden: typeof fs.hidden == "function" ? fs.hidden : fs.hidden ? !0 : f.type.hidden
|
|
2526
|
+
}
|
|
2527
|
+
}))
|
|
2528
|
+
) : schemaType.fields).filter((f) => !["sanity.imageHotspot", "sanity.imageCrop"].includes(f.type?.name ?? "")).filter((f) => isAssistSupported(f.type)).map((field) => serializeMember(schema, field.type, field.name, options2));
|
|
2529
|
+
}
|
|
2530
|
+
function serializeMember(schema, type, name, options2) {
|
|
2531
|
+
const typeName = schema.get(type?.name) ? type.name : type.type?.name ?? "";
|
|
2532
|
+
return removeUndef({
|
|
2533
|
+
...options2?.leanFormat ? {} : { _type: assistSerializedFieldTypeName },
|
|
2534
|
+
name,
|
|
2535
|
+
type: typeName,
|
|
2536
|
+
title: type.title,
|
|
2537
|
+
...getBaseFields(schema, type, typeName, options2)
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
function serializeInlineOf(blockSchemaType, schema, options2) {
|
|
2541
|
+
const childrenType = blockSchemaType.fields.find((f) => f.name === "children")?.type;
|
|
2542
|
+
if (!(!childrenType || !sanity.isArraySchemaType(childrenType)))
|
|
2543
|
+
return arrayOf(
|
|
2544
|
+
{
|
|
2545
|
+
of: childrenType.of.filter((t) => !isType(t, "span"))
|
|
2546
|
+
},
|
|
2547
|
+
schema,
|
|
2548
|
+
options2
|
|
2549
|
+
);
|
|
2550
|
+
}
|
|
2551
|
+
function serializeAnnotations(blockSchemaType, schema, options2) {
|
|
2552
|
+
const marksType = blockSchemaType.fields.find((f) => f.name === "markDefs")?.type;
|
|
2553
|
+
if (!(!marksType || !sanity.isArraySchemaType(marksType)))
|
|
2554
|
+
return arrayOf(marksType, schema, options2);
|
|
2555
|
+
}
|
|
2556
|
+
function arrayOf(arrayType, schema, options2) {
|
|
2557
|
+
return arrayType.of.filter((type) => isAssistSupported(type)).map((t) => serializeMember(schema, t, t.name, options2));
|
|
2558
|
+
}
|
|
2559
|
+
function refToTypeNames(type) {
|
|
2560
|
+
return type.to.map((t) => ({
|
|
2561
|
+
type: sanity.typed(t.name)
|
|
2562
|
+
}));
|
|
2563
|
+
}
|
|
2564
|
+
function removeUndef(obj) {
|
|
2565
|
+
return Object.keys(obj).forEach((key) => obj[key] === void 0 ? delete obj[key] : {}), obj;
|
|
2566
|
+
}
|
|
2567
|
+
function createFieldRefCache() {
|
|
2568
|
+
const byType = {};
|
|
2569
|
+
function getRefsForType(schemaType) {
|
|
2570
|
+
const documentType = schemaType.name, cached = byType[documentType];
|
|
2571
|
+
if (cached) return cached;
|
|
2572
|
+
const fieldRefs = getFieldRefs(schemaType), fieldRefsByTypePath = asFieldRefsByTypePath(fieldRefs), refs = {
|
|
2573
|
+
fieldRefs,
|
|
2574
|
+
fieldRefsByTypePath
|
|
2575
|
+
};
|
|
2576
|
+
return byType[documentType] = refs, refs;
|
|
2577
|
+
}
|
|
2578
|
+
return getRefsForType;
|
|
2579
|
+
}
|
|
2580
|
+
function AiAssistanceConfigProvider(props) {
|
|
2581
|
+
const [status, setStatus] = react.useState(), [error, setError] = react.useState(), apiClient = useApiClient(props.config?.__customApiClient), { getInstructStatus, loading: statusLoading } = useGetInstructStatus(apiClient), { initInstruct, loading: initLoading } = useInitInstruct(apiClient), schema = sanity.useSchema(), serializedTypes = react.useMemo(() => serializeSchema(schema, { leanFormat: !0 }), [schema]), { getFieldRefs: getFieldRefs2, getFieldRefsByTypePath } = useFieldRefGetters(schema);
|
|
2582
|
+
react.useEffect(() => {
|
|
2583
|
+
getInstructStatus().then((s) => setStatus(s)).catch((e) => {
|
|
2584
|
+
console.error(e), setError(e);
|
|
2585
|
+
});
|
|
2586
|
+
}, [getInstructStatus]);
|
|
2587
|
+
const init = react.useCallback(async () => {
|
|
2588
|
+
setError(void 0);
|
|
2589
|
+
try {
|
|
2590
|
+
await initInstruct();
|
|
2591
|
+
const status2 = await getInstructStatus();
|
|
2592
|
+
setStatus(status2);
|
|
2593
|
+
} catch (e) {
|
|
2594
|
+
console.error("Failed to init ai assistance", e), setError(e);
|
|
2595
|
+
}
|
|
2596
|
+
}, [initInstruct, getInstructStatus, setStatus]), { config, children } = props, context = react.useMemo(() => ({
|
|
2597
|
+
config,
|
|
2598
|
+
status,
|
|
2599
|
+
statusLoading,
|
|
2600
|
+
init,
|
|
2601
|
+
initLoading,
|
|
2602
|
+
error,
|
|
2603
|
+
serializedTypes,
|
|
2604
|
+
getFieldRefs: getFieldRefs2,
|
|
2605
|
+
getFieldRefsByTypePath
|
|
2606
|
+
}), [
|
|
2607
|
+
config,
|
|
2608
|
+
status,
|
|
2609
|
+
init,
|
|
2610
|
+
statusLoading,
|
|
2611
|
+
initLoading,
|
|
2612
|
+
error,
|
|
2613
|
+
serializedTypes,
|
|
2614
|
+
getFieldRefs2,
|
|
2615
|
+
getFieldRefsByTypePath
|
|
2616
|
+
]);
|
|
2617
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AiAssistanceConfigContext.Provider, { value: context, children });
|
|
2618
|
+
}
|
|
2619
|
+
function useFieldRefGetters(schema) {
|
|
2620
|
+
return react.useMemo(() => {
|
|
2621
|
+
const getForSchemaType = createFieldRefCache();
|
|
2622
|
+
function getRefsForType(documentType) {
|
|
2623
|
+
const schemaType = schema.get(documentType);
|
|
2624
|
+
if (!schemaType)
|
|
2625
|
+
throw new Error(`Schema type "${documentType}" not found`);
|
|
2626
|
+
return getForSchemaType(schemaType);
|
|
2627
|
+
}
|
|
2628
|
+
return {
|
|
2629
|
+
getFieldRefs: (documentType) => getRefsForType(documentType).fieldRefs,
|
|
2630
|
+
getFieldRefsByTypePath: (documentType) => getRefsForType(documentType).fieldRefsByTypePath
|
|
2631
|
+
};
|
|
2632
|
+
}, [schema]);
|
|
2633
|
+
}
|
|
2599
2634
|
function AssistLayout(props) {
|
|
2600
2635
|
const [connectors, setConnectors] = react.useState([]);
|
|
2601
2636
|
return /* @__PURE__ */ jsxRuntime.jsx(AiAssistanceConfigProvider, { config: props.config, children: /* @__PURE__ */ jsxRuntime.jsx(RunInstructionProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(FieldTranslationProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(ConnectorsProvider, { onConnectorsChange: setConnectors, children: [
|
|
@@ -3181,7 +3216,7 @@ function BackToInstructionListLink() {
|
|
|
3181
3216
|
}
|
|
3182
3217
|
) });
|
|
3183
3218
|
}
|
|
3184
|
-
const EMPTY_FIELDS = [];
|
|
3219
|
+
const SelectedFieldContext = react.createContext(void 0), SelectedFieldContextProvider = SelectedFieldContext.Provider, EMPTY_FIELDS = [];
|
|
3185
3220
|
function AssistDocumentForm(props) {
|
|
3186
3221
|
return props.readOnly ? /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { border: !0, tone: "caution", padding: 2, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: " You do not have sufficient permissions to manage instructions." }) }) : /* @__PURE__ */ jsxRuntime.jsx(AssistDocumentFormEditable, { ...props });
|
|
3187
3222
|
}
|
|
@@ -3681,19 +3716,25 @@ const contextDocumentSchema = sanity.defineType({
|
|
|
3681
3716
|
components: {
|
|
3682
3717
|
input: FieldRefPathInput
|
|
3683
3718
|
},
|
|
3684
|
-
validation: (rule) =>
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3719
|
+
validation: (rule) => {
|
|
3720
|
+
const getForSchemaType = createFieldRefCache();
|
|
3721
|
+
return rule.custom((value, context) => {
|
|
3722
|
+
if (!value)
|
|
3723
|
+
return "Please select a field";
|
|
3724
|
+
try {
|
|
3725
|
+
const docId = context.document?._id;
|
|
3726
|
+
if (!docId)
|
|
3727
|
+
return "Field reference cannot be used outside document inspector context. Could not resolve document id.";
|
|
3728
|
+
const targetDocType = docId.replace(new RegExp(`^${assistDocumentIdPrefix}`), ""), schema = context.schema.get(targetDocType);
|
|
3729
|
+
if (!schema)
|
|
3730
|
+
return `Field reference cannot be used outside document inspector context. Could not resolve schema: ${targetDocType}`;
|
|
3731
|
+
const { fieldRefs } = getForSchemaType(schema);
|
|
3732
|
+
return fieldRefs.find((r) => r.key === value) ? !0 : `Field with path "${value}" does not exist in the schema.`;
|
|
3733
|
+
} catch (e) {
|
|
3734
|
+
return console.error("Failed to resolve field reference", e), "Invalid field reference.";
|
|
3735
|
+
}
|
|
3736
|
+
});
|
|
3737
|
+
}
|
|
3697
3738
|
})
|
|
3698
3739
|
],
|
|
3699
3740
|
preview: {
|