From 728ad0053f335ae6090aaef49d567eb0e870b373 Mon Sep 17 00:00:00 2001 From: Ben Life Date: Fri, 28 Aug 2026 16:25:13 -0400 Subject: [PATCH] update entity field assumptions --- .../local-editor/entityFields.test.ts | 66 +++++++++++++++++++ .../vite-plugin/local-editor/entityFields.ts | 17 +++-- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/packages/visual-editor/src/vite-plugin/local-editor/entityFields.test.ts b/packages/visual-editor/src/vite-plugin/local-editor/entityFields.test.ts index 1dfbb6b83d..ad7d040d52 100644 --- a/packages/visual-editor/src/vite-plugin/local-editor/entityFields.test.ts +++ b/packages/visual-editor/src/vite-plugin/local-editor/entityFields.test.ts @@ -69,6 +69,72 @@ describe("inferEntityFields", () => { ); }); + it("does not classify an object containing an image field as type.image", () => { + const inferred = inferEntityFields( + { + c_aboutSection: { + title: "About", + description: { + html: "

Description

", + }, + image: { + url: "https://example.com/about.jpg", + width: 1200, + height: 800, + }, + cta: { + label: "Learn more", + link: "/about", + linkType: "URL", + }, + }, + }, + { + fields: [ + "c_aboutSection.title", + "c_aboutSection.description.html", + "c_aboutSection.image", + "c_aboutSection.cta", + ], + } + ); + + const aboutSection = inferred.fields.find( + (field) => field.name === "c_aboutSection" + ); + + expect(aboutSection?.definition.typeRegistryId).toBe("type.object"); + expect(aboutSection?.children?.fields).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: "description", + displayName: "About Section > Description", + definition: expect.objectContaining({ + typeRegistryId: "type.rich_text_v2", + }), + }), + expect.objectContaining({ + name: "image", + definition: expect.objectContaining({ + typeRegistryId: "type.image", + }), + }), + expect.objectContaining({ + name: "cta", + definition: expect.objectContaining({ + typeRegistryId: "type.cta", + }), + }), + expect.objectContaining({ + name: "title", + definition: expect.objectContaining({ + typeRegistryId: "type.string", + }), + }), + ]) + ); + }); + it("does not classify unrelated json-shaped objects as rich text", () => { const inferred = inferEntityFields({ analyticsPayload: { diff --git a/packages/visual-editor/src/vite-plugin/local-editor/entityFields.ts b/packages/visual-editor/src/vite-plugin/local-editor/entityFields.ts index 77b08be2ae..2b8dc8aa4e 100644 --- a/packages/visual-editor/src/vite-plugin/local-editor/entityFields.ts +++ b/packages/visual-editor/src/vite-plugin/local-editor/entityFields.ts @@ -217,11 +217,10 @@ const inferStructuredObjectType = ( }; const isImageValue = (value: Record): boolean => { - const nestedImage = value.image; - if (isPlainObject(nestedImage) && isImageValue(nestedImage)) { - return true; - } + return isDirectImageValue(value) || isComplexImageValue(value); +}; +const isDirectImageValue = (value: Record): boolean => { return ( typeof value.url === "string" && (typeof value.alternateText === "string" || @@ -230,6 +229,16 @@ const isImageValue = (value: Record): boolean => { ); }; +const isComplexImageValue = (value: Record): boolean => { + const valueKeys = Object.keys(value); + if (valueKeys.length !== 1 || valueKeys[0] !== "image") { + return false; + } + + const nestedImage = value.image; + return isPlainObject(nestedImage) && isDirectImageValue(nestedImage); +}; + const isCtaValue = (value: Record): boolean => { return ( (typeof value.label === "string" || typeof value.link === "string") &&