@elementor/editor-variables 4.3.0-976 → 4.3.0-978

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-variables",
3
- "version": "4.3.0-976",
3
+ "version": "4.3.0-978",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -39,22 +39,22 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor": "4.3.0-976",
43
- "@elementor/editor-canvas": "4.3.0-976",
44
- "@elementor/editor-controls": "4.3.0-976",
45
- "@elementor/editor-current-user": "4.3.0-976",
46
- "@elementor/editor-mcp": "4.3.0-976",
47
- "@elementor/editor-panels": "4.3.0-976",
48
- "@elementor/editor-props": "4.3.0-976",
49
- "@elementor/editor-ui": "4.3.0-976",
50
- "@elementor/editor-v1-adapters": "4.3.0-976",
51
- "@elementor/menus": "4.3.0-976",
52
- "@elementor/http-client": "4.3.0-976",
42
+ "@elementor/editor": "4.3.0-978",
43
+ "@elementor/editor-canvas": "4.3.0-978",
44
+ "@elementor/editor-controls": "4.3.0-978",
45
+ "@elementor/editor-current-user": "4.3.0-978",
46
+ "@elementor/editor-mcp": "4.3.0-978",
47
+ "@elementor/editor-panels": "4.3.0-978",
48
+ "@elementor/editor-props": "4.3.0-978",
49
+ "@elementor/editor-ui": "4.3.0-978",
50
+ "@elementor/editor-v1-adapters": "4.3.0-978",
51
+ "@elementor/menus": "4.3.0-978",
52
+ "@elementor/http-client": "4.3.0-978",
53
53
  "@elementor/icons": "~1.75.1",
54
- "@elementor/events": "4.3.0-976",
55
- "@elementor/schema": "4.3.0-976",
54
+ "@elementor/events": "4.3.0-978",
55
+ "@elementor/schema": "4.3.0-978",
56
56
  "@elementor/ui": "1.37.5",
57
- "@elementor/utils": "4.3.0-976",
57
+ "@elementor/utils": "4.3.0-978",
58
58
  "@wordpress/i18n": "^5.13.0"
59
59
  },
60
60
  "peerDependencies": {
@@ -1,13 +1,14 @@
1
1
  import { type MCPRegistryEntry } from '@elementor/editor-mcp';
2
+ import { type HttpResponse, httpService } from '@elementor/http-client';
2
3
  import { z } from '@elementor/schema';
3
4
  import { isProActive } from '@elementor/utils';
4
5
 
5
- import { service } from '../service';
6
- import { getFontConfigs } from '../sync/get-font-configs';
7
- import { validateLabel } from '../utils/validations';
8
- import { generateVariablesPrompt, MANAGE_VARIABLES_GUIDE_URI } from './variable-tool-prompt';
6
+ import { MANAGE_VARIABLES_GUIDE_URI } from './variable-tool-prompt';
9
7
  import { GLOBAL_VARIABLES_URI } from './variables-resource';
10
8
 
9
+ const MCP_PROXY_URL = 'elementor/v1/mcp-proxy';
10
+ const TOOL_NAME = 'manage-global-variable';
11
+
11
12
  const VARIABLE_TYPES = {
12
13
  COLOR: 'global-color-variable',
13
14
  FONT: 'global-font-variable',
@@ -15,36 +16,6 @@ const VARIABLE_TYPES = {
15
16
  CUSTOM_SIZE: 'global-custom-size-variable',
16
17
  } as const;
17
18
 
18
- const LENGTH_UNIT_PATTERN = /^(auto|\d+(\.\d+)?(px|rem|em|vh|vw|%|ch|s|ms))$/i;
19
- const COLOR_PATTERN = /^(#[0-9a-f]{3,8}|rgba?\(|hsl)/i;
20
-
21
- function validateValueForType( type: string, value: string ): string | null {
22
- if ( type === VARIABLE_TYPES.FONT && LENGTH_UNIT_PATTERN.test( value.trim() ) ) {
23
- return `Font variable value must be a font family name (e.g. "Roboto"), not a size value like "${ value }". Use "global-size-variable" or "global-custom-size-variable" for spacing/size values.`;
24
- }
25
-
26
- if ( type === VARIABLE_TYPES.COLOR && ! COLOR_PATTERN.test( value.trim() ) ) {
27
- return `Color variable value should be a CSS color (e.g. "#FF0000"), got "${ value }".`;
28
- }
29
-
30
- if ( type === VARIABLE_TYPES.SIZE && ! LENGTH_UNIT_PATTERN.test( value.trim() ) ) {
31
- return `Size variable value should include a CSS unit (e.g. "16px") or be "auto", got "${ value }".`;
32
- }
33
-
34
- if ( type === VARIABLE_TYPES.FONT && ! isFontAvailable( value ) ) {
35
- return `Font "${ value }" is not supported in WordPress. Please choose one of the available font families.`;
36
- }
37
-
38
- return null;
39
- }
40
-
41
- function isFontAvailable( font: string ) {
42
- const fonts = getFontConfigs();
43
- const key = font.trim();
44
-
45
- return !! fonts?.[ key ];
46
- }
47
-
48
19
  export const initManageVariableTool = ( reg: MCPRegistryEntry ) => {
49
20
  const { addTool, resource } = reg;
50
21
  const RUNTIME_ALLOWED_VARIABLE_TYPES = isProActive()
@@ -59,13 +30,19 @@ export const initManageVariableTool = ( reg: MCPRegistryEntry ) => {
59
30
  description: 'Detailed guide for using the manage-global-variable tool',
60
31
  mimeType: 'text/plain',
61
32
  },
62
- async ( uri: URL ) => ( {
63
- contents: [ { uri: uri.href, mimeType: 'text/plain', text: generateVariablesPrompt() } ],
64
- } )
33
+ async ( uri: URL ) => {
34
+ const { data } = await httpService().get< HttpResponse< string > >( MCP_PROXY_URL, {
35
+ params: { uri: uri.href },
36
+ } );
37
+
38
+ return {
39
+ contents: [ { uri: uri.href, mimeType: 'text/plain', text: data.data } ],
40
+ };
41
+ }
65
42
  );
66
43
 
67
44
  addTool( {
68
- name: 'manage-global-variable',
45
+ name: TOOL_NAME,
69
46
  description:
70
47
  'Manage V4 global variables (color, font, size, custom-size). Read the guide resource before use. font = font-famliy, size = measured unit, custom-size = calculated values',
71
48
  schema: {
@@ -96,62 +73,12 @@ export const initManageVariableTool = ( reg: MCPRegistryEntry ) => {
96
73
  ],
97
74
  isDestructive: true,
98
75
  handler: async ( params ) => {
99
- const operations = getServiceActions( service );
100
- const op = operations[ params.action ];
101
- if ( op ) {
102
- await op( params );
103
- return { status: 'ok' };
104
- }
105
- throw new Error( `Unknown action ${ params.action }` );
76
+ await httpService().post( MCP_PROXY_URL, {
77
+ tool: TOOL_NAME,
78
+ input: params,
79
+ } );
80
+
81
+ return { status: 'ok' };
106
82
  },
107
83
  } );
108
84
  };
109
-
110
- type Opts< T extends Record< string, string > > = Partial< T > & {
111
- [ k: string ]: unknown;
112
- };
113
-
114
- function getServiceActions( svc: typeof service ) {
115
- return {
116
- create( { type, label, value }: Opts< { type: string; label: string; value: string } > ) {
117
- if ( ! type || ! label || ! value ) {
118
- throw new Error( 'Create requires type, label, and value' );
119
- }
120
- if ( ( type === VARIABLE_TYPES.SIZE || type === VARIABLE_TYPES.CUSTOM_SIZE ) && ! isProActive() ) {
121
- throw new Error( 'Creating size variables requires Elementor Pro.' );
122
- }
123
- const labelError = validateLabel( label );
124
- if ( labelError ) {
125
- throw new Error( labelError );
126
- }
127
- const valueError = validateValueForType( type, value );
128
- if ( valueError ) {
129
- throw new Error( valueError );
130
- }
131
- return svc.create( { type, label, value }, { eventData: { executedBy: 'mcp_tool' } } );
132
- },
133
- update( { id, label, value }: Opts< { id: string; label: string; value: string } > ) {
134
- if ( ! id || ! label || ! value ) {
135
- throw new Error( 'Update requires id, label, and value' );
136
- }
137
- const labelError = validateLabel( label );
138
- if ( labelError ) {
139
- throw new Error( labelError );
140
- }
141
- const existingVariable = svc.variables()[ id ];
142
- if ( existingVariable ) {
143
- const valueError = validateValueForType( existingVariable.type, value );
144
- if ( valueError ) {
145
- throw new Error( valueError );
146
- }
147
- }
148
- return svc.update( id, { label, value }, { eventData: { executedBy: 'mcp_tool' } } );
149
- },
150
- delete( { id }: Opts< { id: string } > ) {
151
- if ( ! id ) {
152
- throw new Error( 'delete requires id' );
153
- }
154
- return svc.delete( id );
155
- },
156
- };
157
- }
@@ -1,85 +1 @@
1
- import { toolPrompts } from '@elementor/editor-mcp';
2
- import { isProActive } from '@elementor/utils';
3
-
4
1
  export const MANAGE_VARIABLES_GUIDE_URI = 'elementor://variables/tools/manage-global-variable-guide';
5
-
6
- export const generateVariablesPrompt = () => {
7
- const prompt = toolPrompts( 'manage-global-variable' );
8
- const proIsActive = isProActive();
9
-
10
- const sizeVariableSection = proIsActive
11
- ? `- **global-size-variable** — A simple CSS length with a unit (Elementor Pro). Use this for fixed spacing, font sizes, or layout values. Example: \`16px\`, \`1.5rem\`, \`2em\`, \`10vh\`
12
- - **global-custom-size-variable** — Any CSS size expression that goes beyond a simple number + unit (Elementor Pro). Use this when the value is a CSS function, a keyword, or a combination of units that \`global-size-variable\` cannot represent. Example: \`auto\`, \`clamp(1rem, 2vw, 2rem)\`, \`calc(100% - 32px)\`, \`min(50vw, 600px)\`, \`300ms\`, \`2ch\`. When in doubt: if the value contains a function call or a keyword, use \`global-custom-size-variable\`.`
13
- : `- ~~global-size-variable~~ — requires Elementor Pro (not available on this site)
14
- - ~~global-custom-size-variable~~ — requires Elementor Pro (not available on this site)`;
15
-
16
- prompt.description( `
17
- # Purpose
18
- Create, update, or delete V4 global CSS variables. These are distinct from legacy v3 globals and map 1:1 to \`--css-var: VALUE\`.
19
-
20
- # Available Types
21
- - **global-color-variable** — CSS color value. Example: \`#FF0000\`, \`rgba(255,0,0,1)\`, \`hsl(0,100%,50%)\`
22
- - **global-font-variable** — Font family name ONLY — NOT a size or px value. Example: \`Roboto\`, \`Open Sans\`. NEVER pass px/rem here.
23
- ${ sizeVariableSection }
24
-
25
- # Naming Rules
26
- - Labels must be **lowercase**, using only letters (a-z), numbers, digits (0-9), dashes (-), or underscores (_)
27
- - No spaces, no special characters
28
- - Example: "Headline Primary" → \`headline-primary\`
29
- - Labels must be unique — always check [elementor://global-variables] first
30
-
31
- # Value Rules
32
- - Provide a **plain CSS value** only — do NOT pass JSON, legacy-globals object structures, or variable references
33
- - Values are inserted as-is: \`--css-var: <value>\`
34
- - NEVER store a px/rem value inside a \`global-font-variable\` — use \`global-size-variable\` (Pro) instead
35
-
36
- # Operations
37
- - **create** — requires \`type\`, \`label\`, \`value\`. Label must be unique.
38
- - **update** — requires \`id\`, \`label\`, \`value\`. Get \`id\` from [elementor://global-variables]. When renaming: keep existing value. When changing value: keep exact existing label.
39
- - **delete** — requires \`id\`. DESTRUCTIVE — always confirm with user before executing.
40
- ` );
41
-
42
- prompt.parameter( 'action', '"create", "update", or "delete".' );
43
- prompt.parameter( 'type', 'Variable type. Required for create. See Available Types above.' );
44
- prompt.parameter( 'label', 'Variable name (lowercase, dash-separated). Required for create/update.' );
45
- prompt.parameter(
46
- 'value',
47
- 'Plain CSS value matching the variable type. Required for create/update. Do NOT pass JSON.'
48
- );
49
- prompt.parameter( 'id', 'Variable ID. Required for update/delete. Obtain from [elementor://global-variables].' );
50
-
51
- prompt.example( `
52
- Create a brand color:
53
- { "action": "create", "type": "global-color-variable", "label": "brand-primary", "value": "#1A73E8" }
54
-
55
- Create a heading font:
56
- { "action": "create", "type": "global-font-variable", "label": "font-heading", "value": "Playfair Display" }
57
-
58
- Create a simple spacing size:
59
- { "action": "create", "type": "global-size-variable", "label": "spacing-md", "value": "16px" }
60
-
61
- Create a fluid/responsive size using a CSS function (use global-custom-size-variable, NOT global-size-variable):
62
- { "action": "create", "type": "global-custom-size-variable", "label": "spacing-fluid", "value": "clamp(1rem, 2vw, 2rem)" }
63
-
64
- Create a size that is a keyword:
65
- { "action": "create", "type": "global-custom-size-variable", "label": "width-auto", "value": "auto" }
66
-
67
- Create a size using calc():
68
- { "action": "create", "type": "global-custom-size-variable", "label": "sidebar-width", "value": "calc(100% - 32px)" }
69
-
70
- Update a variable's value (keep exact label):
71
- { "action": "update", "id": "abc123", "label": "brand-primary", "value": "#0D47A1" }
72
-
73
- Rename a variable (keep existing value):
74
- { "action": "update", "id": "abc123", "label": "brand-secondary", "value": "#1A73E8" }
75
-
76
- Delete a variable:
77
- { "action": "delete", "id": "abc123" }
78
- ` );
79
-
80
- prompt.instruction(
81
- 'Always read [elementor://global-variables] before creating to check existing variables and avoid duplicate labels.'
82
- );
83
-
84
- return prompt.prompt();
85
- };
@@ -1,33 +1,18 @@
1
1
  import { type MCPRegistryEntry } from '@elementor/editor-mcp';
2
2
  import { __privateListenTo as listenTo, commandEndEvent } from '@elementor/editor-v1-adapters';
3
+ import { type HttpResponse, httpService } from '@elementor/http-client';
3
4
 
4
- import { service } from '../service';
5
- import { STORAGE_UPDATED_EVENT, type TVariable } from '../storage';
5
+ import { STORAGE_UPDATED_EVENT } from '../storage';
6
6
 
7
+ const MCP_PROXY_URL = 'elementor/v1/mcp-proxy';
7
8
  export const GLOBAL_VARIABLES_URI = 'elementor://global-variables';
8
9
 
9
- type GlobalVariablesResourceEntry =
10
- | ( TVariable & { version: 'v4' } )
11
- | ( Record< string, unknown > & { version: 'v3' } );
12
-
13
- const buildGlobalVariablesPayload = async (): Promise< Record< string, GlobalVariablesResourceEntry > > => {
14
- const merged: Record< string, GlobalVariablesResourceEntry > = {};
15
- Object.entries( service.variables() ).forEach( ( [ id, variable ] ) => {
16
- if ( ! variable.deleted ) {
17
- merged[ id ] = { ...variable, version: 'v4' };
18
- }
19
- } );
20
- return merged;
21
- };
22
-
23
10
  export const initVariablesResource = ( variablesMcpEntry: MCPRegistryEntry, canvasMcpEntry: MCPRegistryEntry ) => {
24
11
  [ canvasMcpEntry, variablesMcpEntry ].forEach( ( entry ) => {
25
12
  const { resource, sendResourceUpdated } = entry;
26
13
 
27
14
  const notifyGlobalVariablesUpdated = () => {
28
- sendResourceUpdated( {
29
- uri: GLOBAL_VARIABLES_URI,
30
- } );
15
+ sendResourceUpdated( { uri: GLOBAL_VARIABLES_URI } );
31
16
  };
32
17
 
33
18
  resource(
@@ -36,12 +21,18 @@ export const initVariablesResource = ( variablesMcpEntry: MCPRegistryEntry, canv
36
21
  {
37
22
  description: 'Global variables available (v4)',
38
23
  },
39
- async () => {
40
- const variables = await buildGlobalVariablesPayload();
24
+ async ( uri: URL ) => {
25
+ const { data } = await httpService().get< HttpResponse< Record< string, unknown > > >( MCP_PROXY_URL, {
26
+ params: { uri: uri.href },
27
+ } );
41
28
 
42
29
  return {
43
30
  contents: [
44
- { uri: GLOBAL_VARIABLES_URI, mimeType: 'application/json', text: JSON.stringify( variables ) },
31
+ {
32
+ uri: uri.href,
33
+ mimeType: 'application/json',
34
+ text: JSON.stringify( data.data ?? {} ),
35
+ },
45
36
  ],
46
37
  };
47
38
  }