From 39d382f2c2c1de7ca2be40593f87ddca0cf7857d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 17:40:34 +0100 Subject: [PATCH 01/34] Type inputs --- .../src/components/common/CodeEditor/CodeEditor.svelte | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte index bc88f0f981..3271bd4ad2 100644 --- a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte +++ b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte @@ -10,6 +10,7 @@ closeBracketsKeymap, acceptCompletion, completionStatus, + CompletionContext, } from "@codemirror/autocomplete" import { lineNumbers, @@ -44,11 +45,15 @@ import { javascript } from "@codemirror/lang-javascript" import { EditorModes } from "./" import { themeStore } from "@/stores/portal" - import type { EditorMode } from "@budibase/types" + import type { BindingCompletion, EditorMode } from "@budibase/types" export let label: string | undefined = undefined // TODO: work out what best type fits this - export let completions: any[] = [] + export let completions: ((context: CompletionContext) => Promise<{ + from: number + filter: boolean + options: BindingCompletion[] + } | null>)[] = [] export let mode: EditorMode = EditorModes.Handlebars export let value: string | null = "" export let placeholder: string | null = null From dec7cb97a87bbf98c9968ea4578a1b57a4ea2620 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 17:41:58 +0100 Subject: [PATCH 02/34] Split field and helpers --- .../src/components/common/CodeEditor/index.ts | 19 +++++++++++++++++++ .../common/bindings/BindingPanel.svelte | 7 +++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 0c974e0bf4..4f0cb76861 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -217,6 +217,25 @@ export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => { return coreCompletion } +export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { + async function coreCompletion(context: CompletionContext) { + let jsBinding = context.matchBefore(/\bhelpers\./) + let options = baseCompletions || [] + + if (jsBinding) { + return { + from: jsBinding.from + (jsBinding.to - jsBinding.from), + filter: false, + options, + } + } + + return null + } + + return coreCompletion +} + export const buildBindingInfoNode = ( completion: BindingCompletion, binding: any diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index ffb477012c..6fea2baccf 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -23,6 +23,7 @@ snippetAutoComplete, EditorModes, bindingsToCompletions, + jsHelperAutocomplete, } from "../CodeEditor" import BindingSidePanel from "./BindingSidePanel.svelte" import EvaluationSidePanel from "./EvaluationSidePanel.svelte" @@ -114,10 +115,8 @@ useSnippets?: boolean ) => { const completions: ((_: CompletionContext) => any)[] = [ - jsAutocomplete([ - ...bindingCompletions, - ...getHelperCompletions(EditorModes.JS), - ]), + jsAutocomplete([...bindingCompletions.filter(c => c.label)]), + jsHelperAutocomplete([...getHelperCompletions(EditorModes.JS)]), ] if (useSnippets && snippets) { completions.push(snippetAutoComplete(snippets)) From d42832e22302aa5b3eb74b97fe724fcebd015ad0 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 17:51:50 +0100 Subject: [PATCH 03/34] Increase builder ts target --- packages/builder/tsconfig.build.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/builder/tsconfig.build.json b/packages/builder/tsconfig.build.json index 119fe56c81..77606ef8ed 100644 --- a/packages/builder/tsconfig.build.json +++ b/packages/builder/tsconfig.build.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.build.json", "compilerOptions": { + "target": "es2018", "allowJs": true }, "include": ["./src/**/*"], From 203647d7ec6d404c38e5eaa8d99dc8aadccb6523 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 17:51:59 +0100 Subject: [PATCH 04/34] Filter helpers --- .../src/components/common/CodeEditor/index.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 4f0cb76861..32e7250b23 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -219,14 +219,20 @@ export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => { export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { async function coreCompletion(context: CompletionContext) { - let jsBinding = context.matchBefore(/\bhelpers\./) + let jsBinding = context.matchBefore(/\bhelpers\.\w*/) let options = baseCompletions || [] if (jsBinding) { + const match = jsBinding.text.match(/\bhelpers\.(?\w*)/) + if (!match) { + return null + } + const query = match.groups?.["helper"] || "" + let filtered = bindingFilter(options, query) return { - from: jsBinding.from + (jsBinding.to - jsBinding.from), + from: jsBinding.from + match[0].length, filter: false, - options, + options: filtered, } } From 8c88593eb44707c21b425bf9020d07daed8098b3 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 18:09:44 +0100 Subject: [PATCH 05/34] Fix completion --- .../common/CodeEditor/CodeEditor.svelte | 1 - .../src/components/common/CodeEditor/index.ts | 30 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte index 3271bd4ad2..941cf7a6b1 100644 --- a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte +++ b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte @@ -51,7 +51,6 @@ // TODO: work out what best type fits this export let completions: ((context: CompletionContext) => Promise<{ from: number - filter: boolean options: BindingCompletion[] } | null>)[] = [] export let mode: EditorMode = EditorModes.Handlebars diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 32e7250b23..478bad28a3 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -103,11 +103,11 @@ export const helpersToCompletion = ( detail: "Function", apply: ( view: any, - completion: BindingCompletion, + _completion: BindingCompletion, from: number, to: number ) => { - insertBinding(view, from, to, helperName, mode) + insertBinding(view, from, to, helperName, mode, AutocompleteType.HELPER) }, } }) @@ -230,7 +230,8 @@ export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { const query = match.groups?.["helper"] || "" let filtered = bindingFilter(options, query) return { - from: jsBinding.from + match[0].length, + from: jsBinding.from, + to: jsBinding.from + match[0].length, filter: false, options: filtered, } @@ -243,7 +244,7 @@ export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { } export const buildBindingInfoNode = ( - completion: BindingCompletion, + _completion: BindingCompletion, binding: any ) => { if (!binding.valueHTML || binding.value == null) { @@ -303,18 +304,26 @@ export function jsInsert( return parsedInsert } +const enum AutocompleteType { + BINDING, + HELPER, +} + // Autocomplete apply behaviour export const insertBinding = ( view: any, from: number, to: number, text: string, - mode: { name: "javascript" | "handlebars" } + mode: { name: "javascript" | "handlebars" }, + type: AutocompleteType ) => { let parsedInsert if (mode.name == "javascript") { - parsedInsert = jsInsert(view.state.doc?.toString(), from, to, text) + parsedInsert = jsInsert(view.state.doc?.toString(), from, to, text, { + helper: type === AutocompleteType.HELPER, + }) } else if (mode.name == "handlebars") { parsedInsert = hbInsert(view.state.doc?.toString(), from, to, text) } else { @@ -412,7 +421,14 @@ export const bindingsToCompletions = ( from: number, to: number ) => { - insertBinding(view, from, to, binding.readableBinding, mode) + insertBinding( + view, + from, + to, + binding.readableBinding, + mode, + AutocompleteType.BINDING + ) }, }) return acc From 4619742a5725e0b8d2dd4435653ac4e0f634e61c Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 19:54:06 +0100 Subject: [PATCH 06/34] Clean --- .../builder/src/components/common/bindings/BindingPanel.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index 6fea2baccf..3babc395e6 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -115,7 +115,7 @@ useSnippets?: boolean ) => { const completions: ((_: CompletionContext) => any)[] = [ - jsAutocomplete([...bindingCompletions.filter(c => c.label)]), + jsAutocomplete([...bindingCompletions]), jsHelperAutocomplete([...getHelperCompletions(EditorModes.JS)]), ] if (useSnippets && snippets) { From 1d3c2d33bf0e8cfc67960d97bdaae5ef62a02054 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 20:05:03 +0100 Subject: [PATCH 07/34] Add helper to create keyword --- .../src/components/common/CodeEditor/index.ts | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 478bad28a3..ced07edd1f 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -92,7 +92,7 @@ export const helpersToCompletion = ( const helperSection = buildSectionHeader(type, sectionName, icon, 99) return Object.keys(helpers).flatMap(helperName => { - let helper = helpers[helperName] + const helper = helpers[helperName] return { label: helperName, info: (completion: BindingCompletion) => { @@ -220,9 +220,9 @@ export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => { export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { async function coreCompletion(context: CompletionContext) { let jsBinding = context.matchBefore(/\bhelpers\.\w*/) - let options = baseCompletions || [] if (jsBinding) { + let options = baseCompletions || [] const match = jsBinding.text.match(/\bhelpers\.(?\w*)/) if (!match) { return null @@ -235,6 +235,36 @@ export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { filter: false, options: filtered, } + } else { + const prefix = context.matchBefore(/\b\w+/) + if (prefix && "helpers.".startsWith(prefix.text)) { + return { + from: context.pos - prefix.text.length, + to: context.pos, + filter: false, + options: [ + { + label: "helpers.", + detail: "Helpers utilities", + apply: ( + view: any, + _completion: BindingCompletion, + from: number, + to: number + ) => { + insertBinding( + view, + from, + to, + "helpers.", + EditorModes.JS, + AutocompleteType.TEXT + ) + }, + }, + ], + } + } } return null @@ -307,6 +337,7 @@ export function jsInsert( const enum AutocompleteType { BINDING, HELPER, + TEXT, } // Autocomplete apply behaviour @@ -323,6 +354,7 @@ export const insertBinding = ( if (mode.name == "javascript") { parsedInsert = jsInsert(view.state.doc?.toString(), from, to, text, { helper: type === AutocompleteType.HELPER, + disableWrapping: type === AutocompleteType.TEXT, }) } else if (mode.name == "handlebars") { parsedInsert = hbInsert(view.state.doc?.toString(), from, to, text) From b49c74e37b9f682b72b8d4f9761fc64a38c7bf2f Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 20:15:45 +0100 Subject: [PATCH 08/34] Chain it --- .../src/components/common/CodeEditor/index.ts | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index ced07edd1f..06e1cc8b68 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -7,7 +7,8 @@ import { Helper, Snippet, } from "@budibase/types" -import { CompletionContext } from "@codemirror/autocomplete" +import { CompletionContext, startCompletion } from "@codemirror/autocomplete" +import { EditorView } from "@codemirror/view" export const EditorModes: EditorModesMap = { JS: { @@ -102,7 +103,7 @@ export const helpersToCompletion = ( section: helperSection, detail: "Function", apply: ( - view: any, + view: EditorView, _completion: BindingCompletion, from: number, to: number @@ -139,7 +140,7 @@ export const snippetAutoComplete = (snippets: Snippet[]) => { type: "text", simple: true, apply: ( - view: any, + view: EditorView, completion: BindingCompletion, from: number, to: number @@ -247,7 +248,7 @@ export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { label: "helpers.", detail: "Helpers utilities", apply: ( - view: any, + view: EditorView, _completion: BindingCompletion, from: number, to: number @@ -260,6 +261,9 @@ export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { EditorModes.JS, AutocompleteType.TEXT ) + + // Trigger again the completion, to chain it with the helpers completion + startCompletion(view) }, }, ], @@ -342,7 +346,7 @@ const enum AutocompleteType { // Autocomplete apply behaviour export const insertBinding = ( - view: any, + view: EditorView, from: number, to: number, text: string, @@ -386,7 +390,7 @@ export const insertBinding = ( } export const insertSnippet = ( - view: any, + view: EditorView, from: number, to: number, text: string @@ -448,8 +452,8 @@ export const bindingsToCompletions = ( detail: displayType, section: bindingSectionHeader, apply: ( - view: any, - completion: BindingCompletion, + view: EditorView, + _completion: BindingCompletion, from: number, to: number ) => { From a362ab51202a4fe137e531bb6c7058241b5b3615 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 20:20:55 +0100 Subject: [PATCH 09/34] Simplify --- packages/builder/src/components/common/CodeEditor/index.ts | 3 ++- packages/types/src/ui/bindings/binding.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 06e1cc8b68..e9f554c44f 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -246,7 +246,8 @@ export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { options: [ { label: "helpers.", - detail: "Helpers utilities", + type: "text", + simple: true, apply: ( view: EditorView, _completion: BindingCompletion, diff --git a/packages/types/src/ui/bindings/binding.ts b/packages/types/src/ui/bindings/binding.ts index a770a25a3e..dfcd3c6a6d 100644 --- a/packages/types/src/ui/bindings/binding.ts +++ b/packages/types/src/ui/bindings/binding.ts @@ -3,6 +3,7 @@ export interface BindingCompletion { name: string } label: string + simple?: boolean } export interface EnrichedBinding { From 5f13c7e5c55d5d4622f9f2acc5057d54a997bc21 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 20:33:16 +0100 Subject: [PATCH 10/34] Don't show snipopets on $("") autocomplete --- packages/builder/src/components/common/CodeEditor/index.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index e9f554c44f..3a2d9624a6 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -129,6 +129,13 @@ export const snippetAutoComplete = (snippets: Snippet[]) => { if (!snippets?.length) { return null } + + let jsBinding = context.matchBefore(/\$\("[\s\w]*/) + if (jsBinding) { + // We are handing a js field completion + return null + } + const word = context.matchBefore(/\w*/) if (!word || (word.from == word.to && !context.explicit)) { return null From f08a2af4bc791340b79cb9e34401bfb36bbb5389 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 20:34:14 +0100 Subject: [PATCH 11/34] Check boundaries --- packages/builder/src/components/common/CodeEditor/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 3a2d9624a6..a750ca52a1 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -136,7 +136,7 @@ export const snippetAutoComplete = (snippets: Snippet[]) => { return null } - const word = context.matchBefore(/\w*/) + const word = context.matchBefore(/\b\w*/) if (!word || (word.from == word.to && !context.explicit)) { return null } From 4c8ca259cfdfa7dc7f6ab25f680d2f297bf62852 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 10 Feb 2025 22:50:44 +0100 Subject: [PATCH 12/34] Fix --- .../builder/src/components/common/CodeEditor/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index a750ca52a1..5675ba2968 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -130,8 +130,7 @@ export const snippetAutoComplete = (snippets: Snippet[]) => { return null } - let jsBinding = context.matchBefore(/\$\("[\s\w]*/) - if (jsBinding) { + if (context.matchBefore(/\$\("[\s\w]*/)) { // We are handing a js field completion return null } @@ -227,6 +226,11 @@ export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => { export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { async function coreCompletion(context: CompletionContext) { + if (context.matchBefore(/\$\("[\s\w]*/)) { + // We are handing a js field completion + return null + } + let jsBinding = context.matchBefore(/\bhelpers\.\w*/) if (jsBinding) { From 3e2f255f83883f0b4fc64e6ac39964443217d659 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 10:45:51 +0100 Subject: [PATCH 13/34] Renames --- .../common/CodeEditor/CodeEditor.svelte | 4 +-- .../src/components/common/CodeEditor/index.ts | 26 ++++++++++--------- .../common/bindings/BindingPanel.svelte | 6 ++--- packages/types/src/ui/bindings/binding.ts | 2 +- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte index 941cf7a6b1..4096f4d608 100644 --- a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte +++ b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte @@ -45,13 +45,13 @@ import { javascript } from "@codemirror/lang-javascript" import { EditorModes } from "./" import { themeStore } from "@/stores/portal" - import type { BindingCompletion, EditorMode } from "@budibase/types" + import type { BindingCompletionOption, EditorMode } from "@budibase/types" export let label: string | undefined = undefined // TODO: work out what best type fits this export let completions: ((context: CompletionContext) => Promise<{ from: number - options: BindingCompletion[] + options: BindingCompletionOption[] } | null>)[] = [] export let mode: EditorMode = EditorModes.Handlebars export let value: string | null = "" diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 5675ba2968..bd22677c10 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -2,7 +2,7 @@ import { getManifest } from "@budibase/string-templates" import sanitizeHtml from "sanitize-html" import { groupBy } from "lodash" import { - BindingCompletion, + BindingCompletionOption, EditorModesMap, Helper, Snippet, @@ -96,7 +96,7 @@ export const helpersToCompletion = ( const helper = helpers[helperName] return { label: helperName, - info: (completion: BindingCompletion) => { + info: (completion: BindingCompletionOption) => { return buildHelperInfoNode(completion, helper) }, type: "helper", @@ -104,7 +104,7 @@ export const helpersToCompletion = ( detail: "Function", apply: ( view: EditorView, - _completion: BindingCompletion, + _completion: BindingCompletionOption, from: number, to: number ) => { @@ -147,7 +147,7 @@ export const snippetAutoComplete = (snippets: Snippet[]) => { simple: true, apply: ( view: EditorView, - completion: BindingCompletion, + completion: BindingCompletionOption, from: number, to: number ) => { @@ -158,7 +158,7 @@ export const snippetAutoComplete = (snippets: Snippet[]) => { } } -const bindingFilter = (options: BindingCompletion[], query: string) => { +const bindingFilter = (options: BindingCompletionOption[], query: string) => { return options.filter(completion => { const section_parsed = completion.section.name.toLowerCase() const label_parsed = completion.label.toLowerCase() @@ -171,7 +171,7 @@ const bindingFilter = (options: BindingCompletion[], query: string) => { }) } -export const hbAutocomplete = (baseCompletions: BindingCompletion[]) => { +export const hbAutocomplete = (baseCompletions: BindingCompletionOption[]) => { async function coreCompletion(context: CompletionContext) { let bindingStart = context.matchBefore(EditorModes.Handlebars.match) @@ -198,7 +198,7 @@ export const hbAutocomplete = (baseCompletions: BindingCompletion[]) => { return coreCompletion } -export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => { +export const jsAutocomplete = (baseCompletions: BindingCompletionOption[]) => { async function coreCompletion(context: CompletionContext) { let jsBinding = context.matchBefore(/\$\("[\s\w]*/) let options = baseCompletions || [] @@ -224,7 +224,9 @@ export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => { return coreCompletion } -export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { +export const jsHelperAutocomplete = ( + baseCompletions: BindingCompletionOption[] +) => { async function coreCompletion(context: CompletionContext) { if (context.matchBefore(/\$\("[\s\w]*/)) { // We are handing a js field completion @@ -261,7 +263,7 @@ export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { simple: true, apply: ( view: EditorView, - _completion: BindingCompletion, + _completion: BindingCompletionOption, from: number, to: number ) => { @@ -290,7 +292,7 @@ export const jsHelperAutocomplete = (baseCompletions: BindingCompletion[]) => { } export const buildBindingInfoNode = ( - _completion: BindingCompletion, + _completion: BindingCompletionOption, binding: any ) => { if (!binding.valueHTML || binding.value == null) { @@ -457,7 +459,7 @@ export const bindingsToCompletions = ( acc.push({ label: binding.display?.name || binding.readableBinding || "NO NAME", - info: (completion: BindingCompletion) => { + info: (completion: BindingCompletionOption) => { return buildBindingInfoNode(completion, binding) }, type: "binding", @@ -465,7 +467,7 @@ export const bindingsToCompletions = ( section: bindingSectionHeader, apply: ( view: EditorView, - _completion: BindingCompletion, + _completion: BindingCompletionOption, from: number, to: number ) => { diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index 3babc395e6..ae2c701e92 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -35,7 +35,7 @@ import { BindingMode, SidePanel } from "@budibase/types" import type { EnrichedBinding, - BindingCompletion, + BindingCompletionOption, Snippet, Helper, CaretPositionFn, @@ -100,7 +100,7 @@ } } - const getHBSCompletions = (bindingCompletions: BindingCompletion[]) => { + const getHBSCompletions = (bindingCompletions: BindingCompletionOption[]) => { return [ hbAutocomplete([ ...bindingCompletions, @@ -110,7 +110,7 @@ } const getJSCompletions = ( - bindingCompletions: BindingCompletion[], + bindingCompletions: BindingCompletionOption[], snippets: Snippet[] | null, useSnippets?: boolean ) => { diff --git a/packages/types/src/ui/bindings/binding.ts b/packages/types/src/ui/bindings/binding.ts index dfcd3c6a6d..17141b5567 100644 --- a/packages/types/src/ui/bindings/binding.ts +++ b/packages/types/src/ui/bindings/binding.ts @@ -1,4 +1,4 @@ -export interface BindingCompletion { +export interface BindingCompletionOption { section: { name: string } From 237b1fc9b93bf4d1d8935606200a60d24364a231 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 10:48:28 +0100 Subject: [PATCH 14/34] Create types --- .../src/components/common/CodeEditor/CodeEditor.svelte | 8 +++----- .../builder/src/components/common/CodeEditor/index.ts | 9 ++++++--- .../src/components/common/bindings/BindingPanel.svelte | 4 ++-- packages/builder/src/types/bindings.ts | 7 +++++++ packages/builder/src/types/index.ts | 1 + 5 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 packages/builder/src/types/bindings.ts create mode 100644 packages/builder/src/types/index.ts diff --git a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte index 4096f4d608..495862d1b8 100644 --- a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte +++ b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte @@ -45,14 +45,12 @@ import { javascript } from "@codemirror/lang-javascript" import { EditorModes } from "./" import { themeStore } from "@/stores/portal" - import type { BindingCompletionOption, EditorMode } from "@budibase/types" + import type { EditorMode } from "@budibase/types" + import { BindingCompletion } from "@/types" export let label: string | undefined = undefined // TODO: work out what best type fits this - export let completions: ((context: CompletionContext) => Promise<{ - from: number - options: BindingCompletionOption[] - } | null>)[] = [] + export let completions: BindingCompletion[] = [] export let mode: EditorMode = EditorModes.Handlebars export let value: string | null = "" export let placeholder: string | null = null diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index bd22677c10..65a432b0ae 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -9,6 +9,7 @@ import { } from "@budibase/types" import { CompletionContext, startCompletion } from "@codemirror/autocomplete" import { EditorView } from "@codemirror/view" +import { BindingCompletion } from "@/types" export const EditorModes: EditorModesMap = { JS: { @@ -124,7 +125,7 @@ export const getHelperCompletions = (mode: { }) } -export const snippetAutoComplete = (snippets: Snippet[]) => { +export const snippetAutoComplete = (snippets: Snippet[]): BindingCompletion => { return function myCompletions(context: CompletionContext) { if (!snippets?.length) { return null @@ -198,7 +199,9 @@ export const hbAutocomplete = (baseCompletions: BindingCompletionOption[]) => { return coreCompletion } -export const jsAutocomplete = (baseCompletions: BindingCompletionOption[]) => { +export const jsAutocomplete = ( + baseCompletions: BindingCompletionOption[] +): BindingCompletion => { async function coreCompletion(context: CompletionContext) { let jsBinding = context.matchBefore(/\$\("[\s\w]*/) let options = baseCompletions || [] @@ -226,7 +229,7 @@ export const jsAutocomplete = (baseCompletions: BindingCompletionOption[]) => { export const jsHelperAutocomplete = ( baseCompletions: BindingCompletionOption[] -) => { +): BindingCompletion => { async function coreCompletion(context: CompletionContext) { if (context.matchBefore(/\$\("[\s\w]*/)) { // We are handing a js field completion diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index ae2c701e92..98b1910e5c 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -43,7 +43,7 @@ JSONValue, } from "@budibase/types" import type { Log } from "@budibase/string-templates" - import type { CompletionContext } from "@codemirror/autocomplete" + import { BindingCompletion } from "@/types" const dispatch = createEventDispatcher() @@ -114,7 +114,7 @@ snippets: Snippet[] | null, useSnippets?: boolean ) => { - const completions: ((_: CompletionContext) => any)[] = [ + const completions: BindingCompletion[] = [ jsAutocomplete([...bindingCompletions]), jsHelperAutocomplete([...getHelperCompletions(EditorModes.JS)]), ] diff --git a/packages/builder/src/types/bindings.ts b/packages/builder/src/types/bindings.ts new file mode 100644 index 0000000000..ff1b08fb36 --- /dev/null +++ b/packages/builder/src/types/bindings.ts @@ -0,0 +1,7 @@ +import { BindingCompletionOption } from "@budibase/types" +import { CompletionContext } from "@codemirror/autocomplete" + +export type BindingCompletion = (context: CompletionContext) => Promise<{ + from: number + options: BindingCompletionOption[] +} | null> diff --git a/packages/builder/src/types/index.ts b/packages/builder/src/types/index.ts new file mode 100644 index 0000000000..f280d975b4 --- /dev/null +++ b/packages/builder/src/types/index.ts @@ -0,0 +1 @@ +export * from "./bindings" From 8fdc787080c256418bd5091f102c054d09173803 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 12:51:13 +0100 Subject: [PATCH 15/34] Typing --- .../src/components/common/CodeEditor/index.ts | 18 ++++++++++-------- packages/builder/src/types/bindings.ts | 4 ++-- packages/types/src/ui/bindings/binding.ts | 4 +++- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 65a432b0ae..a1af4710de 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -89,7 +89,7 @@ export const buildSectionHeader = ( export const helpersToCompletion = ( helpers: Record, mode: { name: "javascript" | "handlebars" } -) => { +): BindingCompletionOption[] => { const { type, name: sectionName, icon } = SECTIONS.HB_HELPER const helperSection = buildSectionHeader(type, sectionName, icon, 99) @@ -117,7 +117,7 @@ export const helpersToCompletion = ( export const getHelperCompletions = (mode: { name: "javascript" | "handlebars" -}) => { +}): BindingCompletionOption[] => { // TODO: manifest needs to be properly typed const manifest: any = getManifest() return Object.keys(manifest).flatMap(key => { @@ -161,19 +161,21 @@ export const snippetAutoComplete = (snippets: Snippet[]): BindingCompletion => { const bindingFilter = (options: BindingCompletionOption[], query: string) => { return options.filter(completion => { - const section_parsed = completion.section.name.toLowerCase() + const section_parsed = completion.section?.name.toLowerCase() const label_parsed = completion.label.toLowerCase() const query_parsed = query.toLowerCase() return ( - section_parsed.includes(query_parsed) || + section_parsed?.includes(query_parsed) || label_parsed.includes(query_parsed) ) }) } -export const hbAutocomplete = (baseCompletions: BindingCompletionOption[]) => { - async function coreCompletion(context: CompletionContext) { +export const hbAutocomplete = ( + baseCompletions: BindingCompletionOption[] +): BindingCompletion => { + function coreCompletion(context: CompletionContext) { let bindingStart = context.matchBefore(EditorModes.Handlebars.match) let options = baseCompletions || [] @@ -202,7 +204,7 @@ export const hbAutocomplete = (baseCompletions: BindingCompletionOption[]) => { export const jsAutocomplete = ( baseCompletions: BindingCompletionOption[] ): BindingCompletion => { - async function coreCompletion(context: CompletionContext) { + function coreCompletion(context: CompletionContext) { let jsBinding = context.matchBefore(/\$\("[\s\w]*/) let options = baseCompletions || [] @@ -230,7 +232,7 @@ export const jsAutocomplete = ( export const jsHelperAutocomplete = ( baseCompletions: BindingCompletionOption[] ): BindingCompletion => { - async function coreCompletion(context: CompletionContext) { + function coreCompletion(context: CompletionContext) { if (context.matchBefore(/\$\("[\s\w]*/)) { // We are handing a js field completion return null diff --git a/packages/builder/src/types/bindings.ts b/packages/builder/src/types/bindings.ts index ff1b08fb36..5772513d01 100644 --- a/packages/builder/src/types/bindings.ts +++ b/packages/builder/src/types/bindings.ts @@ -1,7 +1,7 @@ import { BindingCompletionOption } from "@budibase/types" import { CompletionContext } from "@codemirror/autocomplete" -export type BindingCompletion = (context: CompletionContext) => Promise<{ +export type BindingCompletion = (context: CompletionContext) => { from: number options: BindingCompletionOption[] -} | null> +} | null diff --git a/packages/types/src/ui/bindings/binding.ts b/packages/types/src/ui/bindings/binding.ts index 17141b5567..1be18b6542 100644 --- a/packages/types/src/ui/bindings/binding.ts +++ b/packages/types/src/ui/bindings/binding.ts @@ -1,9 +1,11 @@ export interface BindingCompletionOption { - section: { + section?: { name: string } label: string + text?: string simple?: boolean + apply?: any // TODO } export interface EnrichedBinding { From aba5d8eee89301422e61cc044e1d2b8692f05bc8 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 13:02:32 +0100 Subject: [PATCH 16/34] Fix types --- .../builder/src/components/common/CodeEditor/CodeEditor.svelte | 2 +- .../builder/src/components/common/bindings/BindingPanel.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte index 495862d1b8..7f15775525 100644 --- a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte +++ b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte @@ -46,7 +46,7 @@ import { EditorModes } from "./" import { themeStore } from "@/stores/portal" import type { EditorMode } from "@budibase/types" - import { BindingCompletion } from "@/types" + import type { BindingCompletion } from "@/types" export let label: string | undefined = undefined // TODO: work out what best type fits this diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index 98b1910e5c..f444e217c7 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -43,7 +43,7 @@ JSONValue, } from "@budibase/types" import type { Log } from "@budibase/string-templates" - import { BindingCompletion } from "@/types" + import type { BindingCompletion } from "@/types" const dispatch = createEventDispatcher() From e961b48c67a451d39d6c274bcc1219eb23557ea6 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 14:29:01 +0100 Subject: [PATCH 17/34] Remove multistep autocomplete --- .../src/components/common/CodeEditor/index.ts | 60 +++++-------------- 1 file changed, 14 insertions(+), 46 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index a1af4710de..3a05c74143 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -7,7 +7,7 @@ import { Helper, Snippet, } from "@budibase/types" -import { CompletionContext, startCompletion } from "@codemirror/autocomplete" +import { CompletionContext } from "@codemirror/autocomplete" import { EditorView } from "@codemirror/view" import { BindingCompletion } from "@/types" @@ -131,8 +131,7 @@ export const snippetAutoComplete = (snippets: Snippet[]): BindingCompletion => { return null } - if (context.matchBefore(/\$\("[\s\w]*/)) { - // We are handing a js field completion + if (wrappedAutocompleteMatch(context)) { return null } @@ -201,11 +200,15 @@ export const hbAutocomplete = ( return coreCompletion } +function wrappedAutocompleteMatch(context: CompletionContext) { + return context.matchBefore(/\$\("[\s\w]*/) +} + export const jsAutocomplete = ( baseCompletions: BindingCompletionOption[] ): BindingCompletion => { function coreCompletion(context: CompletionContext) { - let jsBinding = context.matchBefore(/\$\("[\s\w]*/) + let jsBinding = wrappedAutocompleteMatch(context) let options = baseCompletions || [] if (jsBinding) { @@ -233,61 +236,26 @@ export const jsHelperAutocomplete = ( baseCompletions: BindingCompletionOption[] ): BindingCompletion => { function coreCompletion(context: CompletionContext) { - if (context.matchBefore(/\$\("[\s\w]*/)) { - // We are handing a js field completion + if (wrappedAutocompleteMatch(context)) { return null } - let jsBinding = context.matchBefore(/\bhelpers\.\w*/) + let jsBinding = context.matchBefore(/\b(\w+\.?).*/) + if (!jsBinding || !"helpers.".startsWith(jsBinding.text.split(".")[0])) { + return null + } if (jsBinding) { let options = baseCompletions || [] const match = jsBinding.text.match(/\bhelpers\.(?\w*)/) - if (!match) { - return null - } - const query = match.groups?.["helper"] || "" + const query = match?.groups?.["helper"] || "" let filtered = bindingFilter(options, query) return { from: jsBinding.from, - to: jsBinding.from + match[0].length, + to: jsBinding.from + jsBinding.text.length, filter: false, options: filtered, } - } else { - const prefix = context.matchBefore(/\b\w+/) - if (prefix && "helpers.".startsWith(prefix.text)) { - return { - from: context.pos - prefix.text.length, - to: context.pos, - filter: false, - options: [ - { - label: "helpers.", - type: "text", - simple: true, - apply: ( - view: EditorView, - _completion: BindingCompletionOption, - from: number, - to: number - ) => { - insertBinding( - view, - from, - to, - "helpers.", - EditorModes.JS, - AutocompleteType.TEXT - ) - - // Trigger again the completion, to chain it with the helpers completion - startCompletion(view) - }, - }, - ], - } - } } return null From f146b5dda0713c371a74c71fcfde0dc3ce100b37 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 14:47:48 +0100 Subject: [PATCH 18/34] Update autocomplete package --- packages/builder/package.json | 2 +- yarn.lock | 38 ++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/builder/package.json b/packages/builder/package.json index 0fa4687242..bde21ef447 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -53,7 +53,7 @@ "@budibase/shared-core": "*", "@budibase/string-templates": "*", "@budibase/types": "*", - "@codemirror/autocomplete": "^6.7.1", + "@codemirror/autocomplete": "^6.18.4", "@codemirror/commands": "^6.2.4", "@codemirror/lang-javascript": "^6.1.8", "@codemirror/language": "^6.6.0", diff --git a/yarn.lock b/yarn.lock index b2ca6a0568..e0f30c7a17 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2834,7 +2834,7 @@ dependencies: "@bull-board/api" "5.10.2" -"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.7.1": +"@codemirror/autocomplete@^6.0.0": version "6.7.1" resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.7.1.tgz#3364799b78dff70fb8f81615536c52ea53ce40b2" integrity sha512-hSxf9S0uB+GV+gBsjY1FZNo53e1FFdzPceRfCfD1gWOnV6o21GfB5J5Wg9G/4h76XZMPrF0A6OCK/Rz5+V1egg== @@ -2844,6 +2844,16 @@ "@codemirror/view" "^6.6.0" "@lezer/common" "^1.0.0" +"@codemirror/autocomplete@^6.18.4": + version "6.18.4" + resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.4.tgz#4394f55d6771727179f2e28a871ef46bbbeb11b1" + integrity sha512-sFAphGQIqyQZfP2ZBsSHV7xQvo9Py0rV0dW7W3IMRdS+zDuNb2l3no78CvUaWKGfzFjI4FTrLdUSj86IGb2hRA== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.17.0" + "@lezer/common" "^1.0.0" + "@codemirror/commands@^6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.2.4.tgz#b8a0e5ce72448c092ba4c4b1d902e6f183948aec" @@ -2893,6 +2903,13 @@ resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.2.0.tgz#a0fb08403ced8c2a68d1d0acee926bd20be922f2" integrity sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA== +"@codemirror/state@^6.5.0": + version "6.5.2" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.2.tgz#8eca3a64212a83367dc85475b7d78d5c9b7076c6" + integrity sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA== + dependencies: + "@marijn/find-cluster-break" "^1.0.0" + "@codemirror/theme-one-dark@^6.1.2": version "6.1.2" resolved "https://registry.yarnpkg.com/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz#fcef9f9cfc17a07836cb7da17c9f6d7231064df8" @@ -2912,6 +2929,15 @@ style-mod "^4.0.0" w3c-keyname "^2.2.4" +"@codemirror/view@^6.17.0": + version "6.36.2" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.36.2.tgz#aeb644e161440734ac5a153bf6e5b4a4355047be" + integrity sha512-DZ6ONbs8qdJK0fdN7AB82CgI6tYXf4HWk1wSVa0+9bhVznCuuvhQtX8bFBoy3dv8rZSQqUd8GvhVAcielcidrA== + dependencies: + "@codemirror/state" "^6.5.0" + style-mod "^4.1.0" + w3c-keyname "^2.2.4" + "@colors/colors@1.6.0", "@colors/colors@^1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" @@ -4133,6 +4159,11 @@ semver "^7.3.5" tar "^6.1.11" +"@marijn/find-cluster-break@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz#775374306116d51c0c500b8c4face0f9a04752d8" + integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g== + "@mongodb-js/saslprep@^1.1.5": version "1.1.7" resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz#d1700facfd6916c50c2c88fd6d48d363a56c702f" @@ -19961,6 +19992,11 @@ style-mod@^4.0.0: resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.3.tgz#136c4abc905f82a866a18b39df4dc08ec762b1ad" integrity sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw== +style-mod@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.1.2.tgz#ca238a1ad4786520f7515a8539d5a63691d7bf67" + integrity sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw== + stylus-lookup@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd" From bf03cd94be7e6de2e0ea239d61ce8edeef069510 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 14:48:49 +0100 Subject: [PATCH 19/34] Move and use existing types --- .../builder/src/components/common/CodeEditor/index.ts | 9 ++------- .../src/components/common/bindings/BindingPanel.svelte | 3 +-- packages/builder/src/types/bindings.ts | 7 ++++--- packages/types/src/ui/bindings/binding.ts | 10 ---------- 4 files changed, 7 insertions(+), 22 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 3a05c74143..3ddae61449 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -1,15 +1,10 @@ import { getManifest } from "@budibase/string-templates" import sanitizeHtml from "sanitize-html" import { groupBy } from "lodash" -import { - BindingCompletionOption, - EditorModesMap, - Helper, - Snippet, -} from "@budibase/types" +import { EditorModesMap, Helper, Snippet } from "@budibase/types" import { CompletionContext } from "@codemirror/autocomplete" import { EditorView } from "@codemirror/view" -import { BindingCompletion } from "@/types" +import { BindingCompletion, BindingCompletionOption } from "@/types" export const EditorModes: EditorModesMap = { JS: { diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index f444e217c7..c0548b6292 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -35,7 +35,6 @@ import { BindingMode, SidePanel } from "@budibase/types" import type { EnrichedBinding, - BindingCompletionOption, Snippet, Helper, CaretPositionFn, @@ -43,7 +42,7 @@ JSONValue, } from "@budibase/types" import type { Log } from "@budibase/string-templates" - import type { BindingCompletion } from "@/types" + import type { BindingCompletion, BindingCompletionOption } from "@/types" const dispatch = createEventDispatcher() diff --git a/packages/builder/src/types/bindings.ts b/packages/builder/src/types/bindings.ts index 5772513d01..00571f1d8b 100644 --- a/packages/builder/src/types/bindings.ts +++ b/packages/builder/src/types/bindings.ts @@ -1,7 +1,8 @@ -import { BindingCompletionOption } from "@budibase/types" -import { CompletionContext } from "@codemirror/autocomplete" +import { CompletionContext, Completion } from "@codemirror/autocomplete" export type BindingCompletion = (context: CompletionContext) => { from: number - options: BindingCompletionOption[] + options: Completion[] } | null + +export type BindingCompletionOption = Completion diff --git a/packages/types/src/ui/bindings/binding.ts b/packages/types/src/ui/bindings/binding.ts index 1be18b6542..fdeb4a6c13 100644 --- a/packages/types/src/ui/bindings/binding.ts +++ b/packages/types/src/ui/bindings/binding.ts @@ -1,13 +1,3 @@ -export interface BindingCompletionOption { - section?: { - name: string - } - label: string - text?: string - simple?: boolean - apply?: any // TODO -} - export interface EnrichedBinding { runtimeBinding: string readableBinding: string From 2271dbfdf3c7626f7c3ed85eea1c6ad651ee4c56 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 15:02:08 +0100 Subject: [PATCH 20/34] Undo yarn.lock changes --- yarn.lock | 69 ++++--------------------------------------------------- 1 file changed, 4 insertions(+), 65 deletions(-) diff --git a/yarn.lock b/yarn.lock index e0f30c7a17..2a1aefad7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2834,7 +2834,7 @@ dependencies: "@bull-board/api" "5.10.2" -"@codemirror/autocomplete@^6.0.0": +"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.7.1": version "6.7.1" resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.7.1.tgz#3364799b78dff70fb8f81615536c52ea53ce40b2" integrity sha512-hSxf9S0uB+GV+gBsjY1FZNo53e1FFdzPceRfCfD1gWOnV6o21GfB5J5Wg9G/4h76XZMPrF0A6OCK/Rz5+V1egg== @@ -2844,16 +2844,6 @@ "@codemirror/view" "^6.6.0" "@lezer/common" "^1.0.0" -"@codemirror/autocomplete@^6.18.4": - version "6.18.4" - resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.4.tgz#4394f55d6771727179f2e28a871ef46bbbeb11b1" - integrity sha512-sFAphGQIqyQZfP2ZBsSHV7xQvo9Py0rV0dW7W3IMRdS+zDuNb2l3no78CvUaWKGfzFjI4FTrLdUSj86IGb2hRA== - dependencies: - "@codemirror/language" "^6.0.0" - "@codemirror/state" "^6.0.0" - "@codemirror/view" "^6.17.0" - "@lezer/common" "^1.0.0" - "@codemirror/commands@^6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.2.4.tgz#b8a0e5ce72448c092ba4c4b1d902e6f183948aec" @@ -2903,13 +2893,6 @@ resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.2.0.tgz#a0fb08403ced8c2a68d1d0acee926bd20be922f2" integrity sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA== -"@codemirror/state@^6.5.0": - version "6.5.2" - resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.2.tgz#8eca3a64212a83367dc85475b7d78d5c9b7076c6" - integrity sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA== - dependencies: - "@marijn/find-cluster-break" "^1.0.0" - "@codemirror/theme-one-dark@^6.1.2": version "6.1.2" resolved "https://registry.yarnpkg.com/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz#fcef9f9cfc17a07836cb7da17c9f6d7231064df8" @@ -2929,15 +2912,6 @@ style-mod "^4.0.0" w3c-keyname "^2.2.4" -"@codemirror/view@^6.17.0": - version "6.36.2" - resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.36.2.tgz#aeb644e161440734ac5a153bf6e5b4a4355047be" - integrity sha512-DZ6ONbs8qdJK0fdN7AB82CgI6tYXf4HWk1wSVa0+9bhVznCuuvhQtX8bFBoy3dv8rZSQqUd8GvhVAcielcidrA== - dependencies: - "@codemirror/state" "^6.5.0" - style-mod "^4.1.0" - w3c-keyname "^2.2.4" - "@colors/colors@1.6.0", "@colors/colors@^1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" @@ -4159,11 +4133,6 @@ semver "^7.3.5" tar "^6.1.11" -"@marijn/find-cluster-break@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz#775374306116d51c0c500b8c4face0f9a04752d8" - integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g== - "@mongodb-js/saslprep@^1.1.5": version "1.1.7" resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz#d1700facfd6916c50c2c88fd6d48d363a56c702f" @@ -19766,16 +19735,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -19867,7 +19827,7 @@ stringify-object@^3.2.1: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -19881,13 +19841,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -19992,11 +19945,6 @@ style-mod@^4.0.0: resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.3.tgz#136c4abc905f82a866a18b39df4dc08ec762b1ad" integrity sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw== -style-mod@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.1.2.tgz#ca238a1ad4786520f7515a8539d5a63691d7bf67" - integrity sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw== - stylus-lookup@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd" @@ -21645,7 +21593,7 @@ worker-farm@1.7.0: dependencies: errno "~0.1.7" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -21663,15 +21611,6 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 4ee369060efdc39b23dcc37acf6a60e9c19e7c07 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 15:04:42 +0100 Subject: [PATCH 21/34] Update autocomplete --- packages/builder/package.json | 2 +- yarn.lock | 75 +++++++++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/packages/builder/package.json b/packages/builder/package.json index bde21ef447..a70d19209e 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -53,7 +53,7 @@ "@budibase/shared-core": "*", "@budibase/string-templates": "*", "@budibase/types": "*", - "@codemirror/autocomplete": "^6.18.4", + "@codemirror/autocomplete": "6.9.0", "@codemirror/commands": "^6.2.4", "@codemirror/lang-javascript": "^6.1.8", "@codemirror/language": "^6.6.0", diff --git a/yarn.lock b/yarn.lock index 2a1aefad7a..dffd980299 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2834,16 +2834,26 @@ dependencies: "@bull-board/api" "5.10.2" -"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.7.1": - version "6.7.1" - resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.7.1.tgz#3364799b78dff70fb8f81615536c52ea53ce40b2" - integrity sha512-hSxf9S0uB+GV+gBsjY1FZNo53e1FFdzPceRfCfD1gWOnV6o21GfB5J5Wg9G/4h76XZMPrF0A6OCK/Rz5+V1egg== +"@codemirror/autocomplete@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.9.0.tgz#1a1e63122288b8f8e1e9d7aff2eb39a83e04d8a9" + integrity sha512-Fbwm0V/Wn3BkEJZRhr0hi5BhCo5a7eBL6LYaliPjOSwCyfOpnjXY59HruSxOUNV+1OYer0Tgx1zRNQttjXyDog== dependencies: "@codemirror/language" "^6.0.0" "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.6.0" "@lezer/common" "^1.0.0" +"@codemirror/autocomplete@^6.0.0": + version "6.18.4" + resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.4.tgz#4394f55d6771727179f2e28a871ef46bbbeb11b1" + integrity sha512-sFAphGQIqyQZfP2ZBsSHV7xQvo9Py0rV0dW7W3IMRdS+zDuNb2l3no78CvUaWKGfzFjI4FTrLdUSj86IGb2hRA== + dependencies: + "@codemirror/language" "^6.0.0" + "@codemirror/state" "^6.0.0" + "@codemirror/view" "^6.17.0" + "@lezer/common" "^1.0.0" + "@codemirror/commands@^6.2.4": version "6.2.4" resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.2.4.tgz#b8a0e5ce72448c092ba4c4b1d902e6f183948aec" @@ -2893,6 +2903,13 @@ resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.2.0.tgz#a0fb08403ced8c2a68d1d0acee926bd20be922f2" integrity sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA== +"@codemirror/state@^6.5.0": + version "6.5.2" + resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.2.tgz#8eca3a64212a83367dc85475b7d78d5c9b7076c6" + integrity sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA== + dependencies: + "@marijn/find-cluster-break" "^1.0.0" + "@codemirror/theme-one-dark@^6.1.2": version "6.1.2" resolved "https://registry.yarnpkg.com/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz#fcef9f9cfc17a07836cb7da17c9f6d7231064df8" @@ -2912,6 +2929,15 @@ style-mod "^4.0.0" w3c-keyname "^2.2.4" +"@codemirror/view@^6.17.0": + version "6.36.2" + resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.36.2.tgz#aeb644e161440734ac5a153bf6e5b4a4355047be" + integrity sha512-DZ6ONbs8qdJK0fdN7AB82CgI6tYXf4HWk1wSVa0+9bhVznCuuvhQtX8bFBoy3dv8rZSQqUd8GvhVAcielcidrA== + dependencies: + "@codemirror/state" "^6.5.0" + style-mod "^4.1.0" + w3c-keyname "^2.2.4" + "@colors/colors@1.6.0", "@colors/colors@^1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" @@ -4133,6 +4159,11 @@ semver "^7.3.5" tar "^6.1.11" +"@marijn/find-cluster-break@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz#775374306116d51c0c500b8c4face0f9a04752d8" + integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g== + "@mongodb-js/saslprep@^1.1.5": version "1.1.7" resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz#d1700facfd6916c50c2c88fd6d48d363a56c702f" @@ -19735,7 +19766,16 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -19827,7 +19867,7 @@ stringify-object@^3.2.1: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -19841,6 +19881,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -19945,6 +19992,11 @@ style-mod@^4.0.0: resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.3.tgz#136c4abc905f82a866a18b39df4dc08ec762b1ad" integrity sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw== +style-mod@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.1.2.tgz#ca238a1ad4786520f7515a8539d5a63691d7bf67" + integrity sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw== + stylus-lookup@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd" @@ -21593,7 +21645,7 @@ worker-farm@1.7.0: dependencies: errno "~0.1.7" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -21611,6 +21663,15 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 11dd47a9d22331173540b8961acdb51d40c67ba5 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 15:37:16 +0100 Subject: [PATCH 22/34] Use display lables and default tools for helpers --- .../src/components/common/CodeEditor/index.ts | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 3ddae61449..6cb0dfe582 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -155,7 +155,7 @@ export const snippetAutoComplete = (snippets: Snippet[]): BindingCompletion => { const bindingFilter = (options: BindingCompletionOption[], query: string) => { return options.filter(completion => { - const section_parsed = completion.section?.name.toLowerCase() + const section_parsed = completion.section?.toString().toLowerCase() const label_parsed = completion.label.toLowerCase() const query_parsed = query.toLowerCase() @@ -235,25 +235,18 @@ export const jsHelperAutocomplete = ( return null } - let jsBinding = context.matchBefore(/\b(\w+\.?).*/) - if (!jsBinding || !"helpers.".startsWith(jsBinding.text.split(".")[0])) { + const word = context.matchBefore(/\b\w*/) + if (!word || (word.from == word.to && !context.explicit)) { return null } - - if (jsBinding) { - let options = baseCompletions || [] - const match = jsBinding.text.match(/\bhelpers\.(?\w*)/) - const query = match?.groups?.["helper"] || "" - let filtered = bindingFilter(options, query) - return { - from: jsBinding.from, - to: jsBinding.from + jsBinding.text.length, - filter: false, - options: filtered, - } + return { + from: word.from, + options: baseCompletions.map(helper => ({ + section: helper.section, + displayLabel: helper.label, + label: `helpers.${helper.label}()`, + })), } - - return null } return coreCompletion From 5d12cc3b7e3e61f7eb1229ef7dc37fad72fbd591 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 15:46:09 +0100 Subject: [PATCH 23/34] Format snippers --- .../src/components/common/CodeEditor/index.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 6cb0dfe582..12b5f8498d 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -137,17 +137,9 @@ export const snippetAutoComplete = (snippets: Snippet[]): BindingCompletion => { return { from: word.from, options: snippets.map(snippet => ({ + section: buildSectionHeader("snippets", "Snippets", "Code", 100), label: `snippets.${snippet.name}`, - type: "text", - simple: true, - apply: ( - view: EditorView, - completion: BindingCompletionOption, - from: number, - to: number - ) => { - insertSnippet(view, from, to, completion.label) - }, + displayLabel: snippet.name, })), } } @@ -239,6 +231,7 @@ export const jsHelperAutocomplete = ( if (!word || (word.from == word.to && !context.explicit)) { return null } + return { from: word.from, options: baseCompletions.map(helper => ({ From cb41ee81c6af8d3f3a19667cd0da0df556e7a7d6 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 15:47:16 +0100 Subject: [PATCH 24/34] Remove unnecessary code --- .../src/components/common/CodeEditor/index.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 12b5f8498d..138477e197 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -357,25 +357,6 @@ export const insertBinding = ( }) } -export const insertSnippet = ( - view: EditorView, - from: number, - to: number, - text: string -) => { - let cursorPos = from + text.length - view.dispatch({ - changes: { - from, - to, - insert: text, - }, - selection: { - anchor: cursorPos, - }, - }) -} - // TODO: typing in this function isn't great export const bindingsToCompletions = ( bindings: any, From af6c4b4b8c338860c1ab33bf045be764d97b4c46 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 15:50:32 +0100 Subject: [PATCH 25/34] Clean code --- .../src/components/common/CodeEditor/index.ts | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 138477e197..c6f65c2f5e 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -22,15 +22,7 @@ export const EditorModes: EditorModesMap = { }, } -export const SECTIONS = { - HB_HELPER: { - name: "Helper", - type: "helper", - icon: "Code", - }, -} - -export const buildHelperInfoNode = (completion: any, helper: Helper) => { +const buildHelperInfoNode = (completion: any, helper: Helper) => { const ele = document.createElement("div") ele.classList.add("info-bubble") @@ -62,7 +54,7 @@ const toSpectrumIcon = (name: string) => { ` } -export const buildSectionHeader = ( +const buildSectionHeader = ( type: string, sectionName: string, icon: string, @@ -81,12 +73,11 @@ export const buildSectionHeader = ( } } -export const helpersToCompletion = ( +const helpersToCompletion = ( helpers: Record, mode: { name: "javascript" | "handlebars" } ): BindingCompletionOption[] => { - const { type, name: sectionName, icon } = SECTIONS.HB_HELPER - const helperSection = buildSectionHeader(type, sectionName, icon, 99) + const helperSection = buildSectionHeader("helper", "Helper", "Code", 99) return Object.keys(helpers).flatMap(helperName => { const helper = helpers[helperName] @@ -245,7 +236,7 @@ export const jsHelperAutocomplete = ( return coreCompletion } -export const buildBindingInfoNode = ( +const buildBindingInfoNode = ( _completion: BindingCompletionOption, binding: any ) => { @@ -313,7 +304,7 @@ const enum AutocompleteType { } // Autocomplete apply behaviour -export const insertBinding = ( +const insertBinding = ( view: EditorView, from: number, to: number, From e56431766bd6f53aedc1f741856eeca0f5b22f61 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 16:06:41 +0100 Subject: [PATCH 26/34] Clean code --- .../src/components/common/CodeEditor/index.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index c6f65c2f5e..c9a91c5a28 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -22,7 +22,7 @@ export const EditorModes: EditorModesMap = { }, } -const buildHelperInfoNode = (completion: any, helper: Helper) => { +const buildHelperInfoNode = (helper: Helper) => { const ele = document.createElement("div") ele.classList.add("info-bubble") @@ -83,9 +83,7 @@ const helpersToCompletion = ( const helper = helpers[helperName] return { label: helperName, - info: (completion: BindingCompletionOption) => { - return buildHelperInfoNode(completion, helper) - }, + info: () => buildHelperInfoNode(helper), type: "helper", section: helperSection, detail: "Function", @@ -236,10 +234,10 @@ export const jsHelperAutocomplete = ( return coreCompletion } -const buildBindingInfoNode = ( - _completion: BindingCompletionOption, - binding: any -) => { +const buildBindingInfoNode = (binding: { + valueHTML: string + value: string | null +}) => { if (!binding.valueHTML || binding.value == null) { return null } @@ -385,9 +383,7 @@ export const bindingsToCompletions = ( acc.push({ label: binding.display?.name || binding.readableBinding || "NO NAME", - info: (completion: BindingCompletionOption) => { - return buildBindingInfoNode(completion, binding) - }, + info: () => buildBindingInfoNode(binding), type: "binding", detail: displayType, section: bindingSectionHeader, From e07cb6fb6893d2762ac5667212a5378026c855a4 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 16:11:32 +0100 Subject: [PATCH 27/34] Type anys --- .../src/components/common/CodeEditor/index.ts | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index c9a91c5a28..cad75cd6bb 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -350,7 +350,7 @@ const insertBinding = ( export const bindingsToCompletions = ( bindings: any, mode: { name: "javascript" | "handlebars" } -) => { +): BindingCompletionOption[] => { const bindingByCategory = groupBy(bindings, "category") const categoryMeta = bindings?.reduce((acc: any, ele: any) => { acc[ele.category] = acc[ele.category] || {} @@ -364,21 +364,22 @@ export const bindingsToCompletions = ( return acc }, {}) - const completions = Object.keys(bindingByCategory).reduce( - (comps: any, catKey: string) => { - const { icon, rank } = categoryMeta[catKey] || {} + const completions = Object.keys(bindingByCategory).reduce< + BindingCompletionOption[] + >((comps, catKey) => { + const { icon, rank } = categoryMeta[catKey] || {} - const bindingSectionHeader = buildSectionHeader( - // @ts-ignore something wrong with this - logically this should be dictionary - bindingByCategory.type, - catKey, - icon || "", - typeof rank == "number" ? rank : 1 - ) + const bindingSectionHeader = buildSectionHeader( + // @ts-ignore something wrong with this - logically this should be dictionary + bindingByCategory.type, + catKey, + icon || "", + typeof rank == "number" ? rank : 1 + ) - return [ - ...comps, - ...bindingByCategory[catKey].reduce((acc, binding) => { + comps.push( + ...bindingByCategory[catKey].reduce( + (acc, binding) => { let displayType = binding.fieldSchema?.type || binding.display?.type acc.push({ label: @@ -404,11 +405,13 @@ export const bindingsToCompletions = ( }, }) return acc - }, []), - ] - }, - [] - ) + }, + [] + ) + ) + + return comps + }, []) return completions } From cc0233eb043c27cad489ecffc6d1931a22ec9fff Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 16:54:45 +0100 Subject: [PATCH 28/34] Fix when typing `.` on helpers. or snippets. --- .../src/components/common/CodeEditor/index.ts | 53 ++++++++----------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index cad75cd6bb..6e2f68a7b6 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -110,28 +110,13 @@ export const getHelperCompletions = (mode: { } export const snippetAutoComplete = (snippets: Snippet[]): BindingCompletion => { - return function myCompletions(context: CompletionContext) { - if (!snippets?.length) { - return null - } - - if (wrappedAutocompleteMatch(context)) { - return null - } - - const word = context.matchBefore(/\b\w*/) - if (!word || (word.from == word.to && !context.explicit)) { - return null - } - return { - from: word.from, - options: snippets.map(snippet => ({ - section: buildSectionHeader("snippets", "Snippets", "Code", 100), - label: `snippets.${snippet.name}`, - displayLabel: snippet.name, - })), - } - } + return setAutocomplete( + snippets.map(snippet => ({ + section: buildSectionHeader("snippets", "Snippets", "Code", 100), + label: `snippets.${snippet.name}`, + displayLabel: snippet.name, + })) + ) } const bindingFilter = (options: BindingCompletionOption[], query: string) => { @@ -211,27 +196,33 @@ export const jsAutocomplete = ( export const jsHelperAutocomplete = ( baseCompletions: BindingCompletionOption[] ): BindingCompletion => { - function coreCompletion(context: CompletionContext) { + return setAutocomplete( + baseCompletions.map(helper => ({ + section: helper.section, + displayLabel: helper.label, + label: `helpers.${helper.label}()`, + })) + ) +} + +function setAutocomplete( + options: BindingCompletionOption[] +): BindingCompletion { + return function (context: CompletionContext) { if (wrappedAutocompleteMatch(context)) { return null } - const word = context.matchBefore(/\b\w*/) + const word = context.matchBefore(/\b\w*(\.\w*)?/) if (!word || (word.from == word.to && !context.explicit)) { return null } return { from: word.from, - options: baseCompletions.map(helper => ({ - section: helper.section, - displayLabel: helper.label, - label: `helpers.${helper.label}()`, - })), + options, } } - - return coreCompletion } const buildBindingInfoNode = (binding: { From affaf45d4ff5013ebfb540849bd66bd650d65912 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 17:02:04 +0100 Subject: [PATCH 29/34] Update --- packages/builder/src/components/common/CodeEditor/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 6e2f68a7b6..5fa7224d11 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -77,7 +77,7 @@ const helpersToCompletion = ( helpers: Record, mode: { name: "javascript" | "handlebars" } ): BindingCompletionOption[] => { - const helperSection = buildSectionHeader("helper", "Helper", "Code", 99) + const helperSection = buildSectionHeader("helper", "Helpers", "Code", 99) return Object.keys(helpers).flatMap(helperName => { const helper = helpers[helperName] From 7c91ce89587f3a9c71a1b7a30c26ca918b49c267 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 11 Feb 2025 17:03:26 +0100 Subject: [PATCH 30/34] Lint --- .../builder/src/components/common/CodeEditor/CodeEditor.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte index 7f15775525..2acde47539 100644 --- a/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte +++ b/packages/builder/src/components/common/CodeEditor/CodeEditor.svelte @@ -10,7 +10,6 @@ closeBracketsKeymap, acceptCompletion, completionStatus, - CompletionContext, } from "@codemirror/autocomplete" import { lineNumbers, From 6cc8fb0cc30af01fd484d0278e3f25da1a42845e Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 12 Feb 2025 16:17:37 +0100 Subject: [PATCH 31/34] Add extra info back --- packages/builder/src/components/common/CodeEditor/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/builder/src/components/common/CodeEditor/index.ts b/packages/builder/src/components/common/CodeEditor/index.ts index 5fa7224d11..5529484665 100644 --- a/packages/builder/src/components/common/CodeEditor/index.ts +++ b/packages/builder/src/components/common/CodeEditor/index.ts @@ -198,7 +198,7 @@ export const jsHelperAutocomplete = ( ): BindingCompletion => { return setAutocomplete( baseCompletions.map(helper => ({ - section: helper.section, + ...helper, displayLabel: helper.label, label: `helpers.${helper.label}()`, })) From ec5111f790730f358851cab44628eb491c786624 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 12 Feb 2025 16:21:33 +0100 Subject: [PATCH 32/34] Remove non-needed target --- packages/builder/tsconfig.build.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/tsconfig.build.json b/packages/builder/tsconfig.build.json index 77606ef8ed..119fe56c81 100644 --- a/packages/builder/tsconfig.build.json +++ b/packages/builder/tsconfig.build.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.build.json", "compilerOptions": { - "target": "es2018", "allowJs": true }, "include": ["./src/**/*"], From 304e66735b2cbe7b9b1b05a8ad643699dce1b173 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 13 Feb 2025 11:54:56 +0100 Subject: [PATCH 33/34] Don't allow helpers on snippets --- .../common/bindings/BindingPanel.svelte | 18 ++++++++++++++---- .../common/bindings/SnippetDrawer.svelte | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index c0548b6292..3edcd34317 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -91,7 +91,10 @@ $: bindingCompletions = bindingsToCompletions(enrichedBindings, editorMode) $: bindingHelpers = new BindingHelpers(getCaretPosition, insertAtPos) $: hbsCompletions = getHBSCompletions(bindingCompletions) - $: jsCompletions = getJSCompletions(bindingCompletions, snippets, useSnippets) + $: jsCompletions = getJSCompletions(bindingCompletions, snippets, { + useHelpers: allowHelpers, + useSnippets, + }) $: { // Ensure a valid side panel option is always selected if (sidePanel && !sidePanelOptions.includes(sidePanel)) { @@ -111,13 +114,20 @@ const getJSCompletions = ( bindingCompletions: BindingCompletionOption[], snippets: Snippet[] | null, - useSnippets?: boolean + config: { + useHelpers: boolean + useSnippets: boolean + } ) => { const completions: BindingCompletion[] = [ jsAutocomplete([...bindingCompletions]), - jsHelperAutocomplete([...getHelperCompletions(EditorModes.JS)]), ] - if (useSnippets && snippets) { + if (config.useHelpers) { + completions.push( + jsHelperAutocomplete([...getHelperCompletions(EditorModes.JS)]) + ) + } + if (config.useSnippets && snippets) { completions.push(snippetAutoComplete(snippets)) } return completions diff --git a/packages/builder/src/components/common/bindings/SnippetDrawer.svelte b/packages/builder/src/components/common/bindings/SnippetDrawer.svelte index f10c44f81f..4862217b13 100644 --- a/packages/builder/src/components/common/bindings/SnippetDrawer.svelte +++ b/packages/builder/src/components/common/bindings/SnippetDrawer.svelte @@ -118,6 +118,7 @@ allowHBS={false} allowJS allowSnippets={false} + allowHelpers={false} showTabBar={false} placeholder="return function(input) ❴ ... ❵" value={code} From 1d81949a982a727e286ef53dca7251e3808052d1 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 13 Feb 2025 12:03:54 +0100 Subject: [PATCH 34/34] Don't autocomplete $("") if there is nothing to autocomplete --- .../src/components/common/bindings/BindingPanel.svelte | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/builder/src/components/common/bindings/BindingPanel.svelte b/packages/builder/src/components/common/bindings/BindingPanel.svelte index 3edcd34317..4bd37bf72c 100644 --- a/packages/builder/src/components/common/bindings/BindingPanel.svelte +++ b/packages/builder/src/components/common/bindings/BindingPanel.svelte @@ -119,9 +119,10 @@ useSnippets: boolean } ) => { - const completions: BindingCompletion[] = [ - jsAutocomplete([...bindingCompletions]), - ] + const completions: BindingCompletion[] = [] + if (bindingCompletions.length) { + completions.push(jsAutocomplete([...bindingCompletions])) + } if (config.useHelpers) { completions.push( jsHelperAutocomplete([...getHelperCompletions(EditorModes.JS)]) @@ -389,7 +390,7 @@ autofocus={autofocusEditor} placeholder={placeholder || "Add bindings by typing $ or use the menu on the right"} - jsBindingWrapping + jsBindingWrapping={bindingCompletions.length > 0} /> {/key} {/if}