Validate fields

This commit is contained in:
Adria Navarro 2025-02-14 11:09:28 +01:00
parent dc2f7d53b4
commit ec2d78829e
3 changed files with 39 additions and 30 deletions

View File

@ -49,11 +49,11 @@
import { EditorModes } from "./" import { EditorModes } from "./"
import { themeStore } from "@/stores/portal" import { themeStore } from "@/stores/portal"
import type { EditorMode } from "@budibase/types" import type { EditorMode } from "@budibase/types"
import type { BindingCompletion, BindingCompletionOption } from "@/types" import type { BindingCompletion, CodeValidator } from "@/types"
export let label: string | undefined = undefined export let label: string | undefined = undefined
export let completions: BindingCompletion[] = [] export let completions: BindingCompletion[] = []
export let options: BindingCompletionOption[] = [] export let validations: CodeValidator | null = null
export let mode: EditorMode = EditorModes.Handlebars export let mode: EditorMode = EditorModes.Handlebars
export let value: string | null = "" export let value: string | null = ""
export let placeholder: string | null = null export let placeholder: string | null = null
@ -252,7 +252,7 @@
async function validateHbsTemplate( async function validateHbsTemplate(
editor: EditorView, editor: EditorView,
template: string, template: string,
helpers: Record<string, any[]> validations: CodeValidator
): Promise<Diagnostic[]> { ): Promise<Diagnostic[]> {
const diagnostics: Diagnostic[] = [] const diagnostics: Diagnostic[] = []
@ -274,7 +274,7 @@
editor.state.doc.line(node.loc.end.line).from + editor.state.doc.line(node.loc.end.line).from +
node.loc.end.column node.loc.end.column
if (!(helperName in helpers)) { if (!(helperName in validations)) {
diagnostics.push({ diagnostics.push({
from, from,
to, to,
@ -284,22 +284,20 @@
return return
} }
const expectedParams = helpers[helperName] const config = validations[helperName]
if (expectedParams) { const providedParams = node.params
const providedParams = node.params if (providedParams.length !== config.arguments.length) {
if (providedParams.length !== expectedParams.length) { diagnostics.push({
diagnostics.push({ from,
from, to,
to, severity: "error",
severity: "error", message: `Helper "${helperName}" expects ${
message: `Helper "${helperName}" expects ${ config.arguments.length
expectedParams.length } parameters (${config.arguments.join(", ")}), but got ${
} parameters (${expectedParams.join(", ")}), but got ${ providedParams.length
providedParams.length }.`,
}.`, })
})
}
} }
} }
@ -422,26 +420,20 @@
value: string | null, value: string | null,
editor: EditorView, editor: EditorView,
mode: EditorMode, mode: EditorMode,
options: BindingCompletionOption[] validations: CodeValidator | null
) { ) {
if (!value) { if (!value || !validations) {
return return
} }
const expectedHelpers: Record<string, any[]> = {}
for (const option of options) {
expectedHelpers[option.label] = option.args || []
}
if (mode === EditorModes.Handlebars) { if (mode === EditorModes.Handlebars) {
validateHbsTemplate(editor, value, expectedHelpers).then(diagnostics => { validateHbsTemplate(editor, value, validations).then(diagnostics => {
editor?.dispatch(setDiagnostics(editor.state, diagnostics)) editor?.dispatch(setDiagnostics(editor.state, diagnostics))
}) })
} }
} }
$: validate(value, editor, mode, options) $: validate(value, editor, mode, validations)
const initEditor = () => { const initEditor = () => {
const baseExtensions = buildBaseExtensions() const baseExtensions = buildBaseExtensions()

View File

@ -42,7 +42,7 @@
JSONValue, JSONValue,
} from "@budibase/types" } from "@budibase/types"
import type { Log } from "@budibase/string-templates" import type { Log } from "@budibase/string-templates"
import type { BindingCompletion, BindingCompletionOption } from "@/types" import type { CodeValidator } from "@/types"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -103,6 +103,15 @@
snippetAutoComplete(snippetsOptions), snippetAutoComplete(snippetsOptions),
] ]
$: validations = {
...bindingOptions.reduce<CodeValidator>((validations, option) => {
validations[option.label] = {
arguments: [],
}
return validations
}, {}),
}
$: { $: {
// Ensure a valid side panel option is always selected // Ensure a valid side panel option is always selected
if (sidePanel && !sidePanelOptions.includes(sidePanel)) { if (sidePanel && !sidePanelOptions.includes(sidePanel)) {
@ -348,6 +357,7 @@
bind:getCaretPosition bind:getCaretPosition
bind:insertAtPos bind:insertAtPos
{completions} {completions}
{validations}
autofocus={autofocusEditor} autofocus={autofocusEditor}
placeholder={placeholder || placeholder={placeholder ||
"Add bindings by typing {{ or use the menu on the right"} "Add bindings by typing {{ or use the menu on the right"}

View File

@ -8,3 +8,10 @@ export type BindingCompletion = (context: CompletionContext) => {
export interface BindingCompletionOption extends Completion { export interface BindingCompletionOption extends Completion {
args?: any[] args?: any[]
} }
export type CodeValidator = Record<
string,
{
arguments: any[]
}
>