storyblok / field-plugin

Create and deploy Storyblok Field Plugin
https://www.storyblok.com/docs/plugins/field-plugins/introduction
25 stars 3 forks source link

feat(lib): add validateContent (renamed from parseContent) #280

Closed eunjae-lee closed 11 months ago

eunjae-lee commented 11 months ago

What?

This PR adds validateContent to createFieldPlugin() function as a parameter.

Why?

While we don't have a way on the Visual Editor to prevent from saving invalid custom field plugin data, this pull request is the first step towards it by letting people define their validation logic.

This validateContent enables users to

  1. send valid / invalid status and the error message to the Visual Editor
  2. bring better type-safety

The Visual Editor will later use (1) to properly display the error message and prevent from saving invalid data.

(2) was still here since parseContent, to be clear.

Also, we're making validateContent here optional. parseContent used to be a required parameter. It's understandable that going from required -> optional is easy while optional -> required means a breaking change. However, having the parameter required raises the initial learning curve. If they need, they can just add it. And, do we ever want to make "optional -> required" breaking change? Not too sure. Literally we cannot think of any case where we mandate this parameter. If such situation happens, we will introduce the breaking change and bump the major version. Not that big of a deal for users, too.

JIRA: EXT-1987

How to test? (optional)

vercel[bot] commented 11 months ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
plugin-sandbox ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 11, 2023 0:45am
eunjae-lee commented 11 months ago

@johannes-lindgren added you as a reviewer by mistake 😅

BibiSebi commented 11 months ago

@eunjae-lee there is one question that remains from my side. There is a special case while the field plugin is initialized/loaded where the content is not defined yet because there is no initial value, does it still work with the current implementation?

eunjae-lee commented 11 months ago

@eunjae-lee there is one question that remains from my side. There is a special case while the field plugin is initialized/loaded where the content is not defined yet because there is no initial value, does it still work with the current implementation?

You mean, when user just added a field plugin into their story? Then the initial value must be an empty string (by the implementation of the Visual Editor). So I guess it should be handled by user's validateContent. What do you think?

eunjae-lee commented 11 months ago

something's broken. i'll fix it soon.

BibiSebi commented 11 months ago

You mean, when user just added a field plugin into their story? Then the initial value must be an empty string (by the implementation of the Visual Editor). So I guess it should be handled by user's validateContent. What do you think?

What i meant is that previously we had something like

const plugin = useFieldPlugin({
  parseContent: (content: unknown) =>
    typeof content === 'number' ? content : 0,
})

This implementation had a fallback value (in this case the 0). I am wondering if this value was used only in case of invalid input, or also during the initial load where there is no content yet (for a split of second)

We can leave it as is and also check this trough-out the testing.

How I would test it: Open the visual editor, and see if there is a warning message inside the console even if nothing has been changed and the field plugin was only loaded.

eunjae-lee commented 11 months ago

I am wondering if this value was used only in case of invalid input, or also during the initial load where there is no content yet (for a split of second)

@BibiSebi I see what you mean. This value was used also during the initial load, and still is.

As soon as the library calls initialize() in createFieldPlugin.ts and send loaded message to the Visual Editor, the Visual Editor sends back a message called loaded back to the field plugin. And then this onLoaded function is called. It passes the initial content from the Visual Editor to the validateContent function, and uses the output.

https://github.com/storyblok/field-plugin/blob/c0e0b553e3ce6350f73c8e7ffe9b39b4b7b9d440/packages/field-plugin/src/createFieldPlugin/createPluginActions/createPluginActions.ts#L55-L58

Let me know if you need more clarification!