@elementor/elementor-mcp-common 4.1.0-777 → 4.1.0-779
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/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/validation-utils.ts +7 -0
package/dist/index.d.mts
CHANGED
|
@@ -65,6 +65,8 @@ declare function initNonceRefresh(): void;
|
|
|
65
65
|
declare function refreshNonce(): Promise<string>;
|
|
66
66
|
declare function isNonceError(status: number, responseText: string): boolean;
|
|
67
67
|
|
|
68
|
+
declare function requireConfirmationMessage(confirmationMessage: string | undefined, context: string): void;
|
|
69
|
+
|
|
68
70
|
interface WpApiSettings {
|
|
69
71
|
nonce: string;
|
|
70
72
|
root: string;
|
|
@@ -286,4 +288,4 @@ declare const getWp: () => {
|
|
|
286
288
|
declare const getJQuery: () => McpWindow["jQuery"];
|
|
287
289
|
declare const getElementorAiConfig: () => Record<string, unknown> | undefined;
|
|
288
290
|
|
|
289
|
-
export { type ElementorChannels, type ElementorCommandsInstance, type ElementorCommonInstance, type ElementorContainer, type ElementorDocument, type ElementorFrontendInstance, type ElementorInstance, type JQuery, type WpApiSettings, type WpDataInstance, callWpApi, ensureElementorFrontend, extractElementImageData, extractJSONFromResponse, get$e, getAjaxUrl, getElementSettings, getElementor, getElementorAiConfig, getElementorCommon, getElementorFrontend, getGutenbergBlockEditorApis, getJQuery, getWp, getWpApiSettings, hasGutenbergUI, initNonceRefresh, injectElementCSS, isElementorAIActive, isElementorEditor, isElementorEditorReady, isGutenbergEditor, isNonceError, isSelectAllCheckbox, refreshNonce, removeElementCSS, updateElementSettings, updateGutenbergBlockAttributes, validateAndGetGutenbergBlock, waitForElementor, waitForElementorEditor, whenElementorReady };
|
|
291
|
+
export { type ElementorChannels, type ElementorCommandsInstance, type ElementorCommonInstance, type ElementorContainer, type ElementorDocument, type ElementorFrontendInstance, type ElementorInstance, type JQuery, type WpApiSettings, type WpDataInstance, callWpApi, ensureElementorFrontend, extractElementImageData, extractJSONFromResponse, get$e, getAjaxUrl, getElementSettings, getElementor, getElementorAiConfig, getElementorCommon, getElementorFrontend, getGutenbergBlockEditorApis, getJQuery, getWp, getWpApiSettings, hasGutenbergUI, initNonceRefresh, injectElementCSS, isElementorAIActive, isElementorEditor, isElementorEditorReady, isGutenbergEditor, isNonceError, isSelectAllCheckbox, refreshNonce, removeElementCSS, requireConfirmationMessage, updateElementSettings, updateGutenbergBlockAttributes, validateAndGetGutenbergBlock, waitForElementor, waitForElementorEditor, whenElementorReady };
|
package/dist/index.d.ts
CHANGED
|
@@ -65,6 +65,8 @@ declare function initNonceRefresh(): void;
|
|
|
65
65
|
declare function refreshNonce(): Promise<string>;
|
|
66
66
|
declare function isNonceError(status: number, responseText: string): boolean;
|
|
67
67
|
|
|
68
|
+
declare function requireConfirmationMessage(confirmationMessage: string | undefined, context: string): void;
|
|
69
|
+
|
|
68
70
|
interface WpApiSettings {
|
|
69
71
|
nonce: string;
|
|
70
72
|
root: string;
|
|
@@ -286,4 +288,4 @@ declare const getWp: () => {
|
|
|
286
288
|
declare const getJQuery: () => McpWindow["jQuery"];
|
|
287
289
|
declare const getElementorAiConfig: () => Record<string, unknown> | undefined;
|
|
288
290
|
|
|
289
|
-
export { type ElementorChannels, type ElementorCommandsInstance, type ElementorCommonInstance, type ElementorContainer, type ElementorDocument, type ElementorFrontendInstance, type ElementorInstance, type JQuery, type WpApiSettings, type WpDataInstance, callWpApi, ensureElementorFrontend, extractElementImageData, extractJSONFromResponse, get$e, getAjaxUrl, getElementSettings, getElementor, getElementorAiConfig, getElementorCommon, getElementorFrontend, getGutenbergBlockEditorApis, getJQuery, getWp, getWpApiSettings, hasGutenbergUI, initNonceRefresh, injectElementCSS, isElementorAIActive, isElementorEditor, isElementorEditorReady, isGutenbergEditor, isNonceError, isSelectAllCheckbox, refreshNonce, removeElementCSS, updateElementSettings, updateGutenbergBlockAttributes, validateAndGetGutenbergBlock, waitForElementor, waitForElementorEditor, whenElementorReady };
|
|
291
|
+
export { type ElementorChannels, type ElementorCommandsInstance, type ElementorCommonInstance, type ElementorContainer, type ElementorDocument, type ElementorFrontendInstance, type ElementorInstance, type JQuery, type WpApiSettings, type WpDataInstance, callWpApi, ensureElementorFrontend, extractElementImageData, extractJSONFromResponse, get$e, getAjaxUrl, getElementSettings, getElementor, getElementorAiConfig, getElementorCommon, getElementorFrontend, getGutenbergBlockEditorApis, getJQuery, getWp, getWpApiSettings, hasGutenbergUI, initNonceRefresh, injectElementCSS, isElementorAIActive, isElementorEditor, isElementorEditorReady, isGutenbergEditor, isNonceError, isSelectAllCheckbox, refreshNonce, removeElementCSS, requireConfirmationMessage, updateElementSettings, updateGutenbergBlockAttributes, validateAndGetGutenbergBlock, waitForElementor, waitForElementorEditor, whenElementorReady };
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,7 @@ __export(index_exports, {
|
|
|
46
46
|
isSelectAllCheckbox: () => isSelectAllCheckbox,
|
|
47
47
|
refreshNonce: () => refreshNonce,
|
|
48
48
|
removeElementCSS: () => removeElementCSS,
|
|
49
|
+
requireConfirmationMessage: () => requireConfirmationMessage,
|
|
49
50
|
updateElementSettings: () => updateElementSettings,
|
|
50
51
|
updateGutenbergBlockAttributes: () => updateGutenbergBlockAttributes,
|
|
51
52
|
validateAndGetGutenbergBlock: () => validateAndGetGutenbergBlock,
|
|
@@ -423,6 +424,15 @@ function extractJSONFromResponse(responseText) {
|
|
|
423
424
|
return null;
|
|
424
425
|
}
|
|
425
426
|
}
|
|
427
|
+
|
|
428
|
+
// src/validation-utils.ts
|
|
429
|
+
function requireConfirmationMessage(confirmationMessage, context) {
|
|
430
|
+
if (!confirmationMessage || confirmationMessage.trim() === "") {
|
|
431
|
+
throw new Error(
|
|
432
|
+
`LLM Instructions: ${context} changes require user confirmation. You MUST provide a confirmationMessage parameter explaining what will be changed and its impact.`
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
426
436
|
// Annotate the CommonJS export names for ESM import in node:
|
|
427
437
|
0 && (module.exports = {
|
|
428
438
|
callWpApi,
|
|
@@ -451,6 +461,7 @@ function extractJSONFromResponse(responseText) {
|
|
|
451
461
|
isSelectAllCheckbox,
|
|
452
462
|
refreshNonce,
|
|
453
463
|
removeElementCSS,
|
|
464
|
+
requireConfirmationMessage,
|
|
454
465
|
updateElementSettings,
|
|
455
466
|
updateGutenbergBlockAttributes,
|
|
456
467
|
validateAndGetGutenbergBlock,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/editor-detection.ts","../src/elements.ts","../src/nonce-refresh.ts","../src/rest-client.ts"],"sourcesContent":["export {\n\tisGutenbergEditor,\n\tisElementorEditor,\n\tisElementorAIActive,\n\thasGutenbergUI,\n\tensureElementorFrontend,\n\tisElementorEditorReady,\n\twaitForElementorEditor,\n\twaitForElementor,\n\twhenElementorReady,\n} from './editor-detection';\n\nexport {\n\tinjectElementCSS,\n\tremoveElementCSS,\n\tupdateElementSettings,\n\tgetElementSettings,\n\tgetGutenbergBlockEditorApis,\n\tvalidateAndGetGutenbergBlock,\n\tupdateGutenbergBlockAttributes,\n\textractElementImageData,\n\tisSelectAllCheckbox,\n} from './elements';\n\nexport { callWpApi, extractJSONFromResponse } from './rest-client';\n\nexport { initNonceRefresh, refreshNonce, isNonceError } from './nonce-refresh';\n\nexport type {\n\tElementorChannels,\n\tElementorCommandsInstance,\n\tElementorCommonInstance,\n\tElementorContainer,\n\tElementorDocument,\n\tElementorFrontendInstance,\n\tElementorInstance,\n\tJQuery,\n\tWpApiSettings,\n\tWpDataInstance,\n} from './types';\n\nexport {\n\tget$e,\n\tgetAjaxUrl,\n\tgetElementor,\n\tgetElementorAiConfig,\n\tgetElementorCommon,\n\tgetElementorFrontend,\n\tgetJQuery,\n\tgetWp,\n\tgetWpApiSettings,\n} from './utils';\n","import type {\n\tElementorCommandsInstance,\n\tElementorCommonInstance,\n\tElementorFrontendInstance,\n\tElementorInstance,\n\tWpApiSettings,\n\tWpDataInstance,\n} from './types';\n\ninterface McpWindow {\n\telementor?: ElementorInstance;\n\telementorFrontend?: ElementorFrontendInstance;\n\t$e?: ElementorCommandsInstance;\n\telementorCommon?: ElementorCommonInstance;\n\twpApiSettings?: WpApiSettings;\n\tajaxurl?: string;\n\twp?: {\n\t\tdata: WpDataInstance;\n\t};\n\tjQuery?: ( selector: unknown ) => {\n\t\ton: ( event: string, callback: ( event: unknown, data: unknown ) => void ) => void;\n\t\tget?: ( index: number ) => HTMLElement;\n\t};\n\tElementorAiConfig?: Record< string, unknown >;\n}\n\nexport const getElementor = (): ElementorInstance | undefined => ( window as unknown as McpWindow ).elementor;\n\nexport const getElementorFrontend = (): ElementorFrontendInstance | undefined =>\n\t( window as unknown as McpWindow ).elementorFrontend;\n\nexport const get$e = (): ElementorCommandsInstance | undefined => ( window as unknown as McpWindow ).$e;\n\nexport const getElementorCommon = (): ElementorCommonInstance | undefined =>\n\t( window as unknown as McpWindow ).elementorCommon;\n\nexport const getWpApiSettings = (): WpApiSettings | undefined => ( window as unknown as McpWindow ).wpApiSettings;\n\nexport const getAjaxUrl = (): string | undefined => ( window as unknown as McpWindow ).ajaxurl;\n\nexport const getWp = (): { data: WpDataInstance } | undefined => ( window as unknown as McpWindow ).wp;\n\nexport const getJQuery = (): McpWindow[ 'jQuery' ] => ( window as unknown as McpWindow ).jQuery;\n\nexport const getElementorAiConfig = (): Record< string, unknown > | undefined =>\n\t( window as unknown as McpWindow ).ElementorAiConfig;\n","import { get$e, getElementor, getElementorAiConfig, getElementorFrontend, getWp } from './utils';\n\ntype WaitForElementorOptions = {\n\tmaxRetries: number;\n\tretryInterval?: number;\n\tcheckFn: () => boolean;\n};\n\nconst ELEMENTOR_LOAD_TIMEOUT_MS = 5000;\nconst ELEMENTOR_CHECK_INTERVAL_MS = 100;\nconst DEFAULT_MAX_RETRIES = ELEMENTOR_LOAD_TIMEOUT_MS / ELEMENTOR_CHECK_INTERVAL_MS;\n\nconst DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS: WaitForElementorOptions = {\n\tmaxRetries: DEFAULT_MAX_RETRIES,\n\tretryInterval: ELEMENTOR_CHECK_INTERVAL_MS,\n\tcheckFn: () => !! ( getElementor() && get$e() ),\n};\n\nexport function isGutenbergEditor(): boolean {\n\treturn getWp()?.data?.select( 'core/editor' ) !== undefined;\n}\n\nexport function isElementorEditor(): boolean {\n\tconst params = new URLSearchParams( window.location.search );\n\tfor ( const [ , value ] of params.entries() ) {\n\t\tif ( value.includes( 'elementor' ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function isElementorAIActive(): boolean {\n\treturn !! getElementorAiConfig();\n}\n\nexport function hasGutenbergUI(): boolean {\n\treturn !! document.querySelector( '.edit-post-header-toolbar' );\n}\n\nexport function ensureElementorFrontend(): void {\n\tconst frontend = getElementorFrontend() as { elements?: { $body?: unknown } } | undefined;\n\tif ( ! frontend?.elements?.$body ) {\n\t\tthrow new Error( 'elementorFrontend or its required components not available' );\n\t}\n}\n\nexport function isElementorEditorReady(): boolean {\n\treturn !! get$e()?.components.get( 'panel' );\n}\n\nexport function waitForElementorEditor(): Promise< void > {\n\treturn new Promise( ( resolve ) => {\n\t\tif ( isElementorEditorReady() ) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\n\t\tconst checkReady = () => {\n\t\t\tif ( isElementorEditorReady() ) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\tsetTimeout( checkReady, 100 );\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener(\n\t\t\t'DOMContentLoaded',\n\t\t\t() => {\n\t\t\t\tcheckReady();\n\t\t\t},\n\t\t\t{\n\t\t\t\tonce: true,\n\t\t\t}\n\t\t);\n\t} );\n}\n\nexport function waitForElementor(\n\toptions: WaitForElementorOptions = DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS\n): Promise< void > {\n\tconst { maxRetries, retryInterval, checkFn } = options;\n\n\treturn new Promise( ( resolve, reject ) => {\n\t\tlet attempts = 0;\n\n\t\tconst check = () => {\n\t\t\tif ( checkFn() ) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tattempts++;\n\n\t\t\tif ( attempts >= maxRetries ) {\n\t\t\t\treject( new Error( `Elementor not loaded after ${ maxRetries } attempts` ) );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetTimeout( check, retryInterval );\n\t\t};\n\n\t\tcheck();\n\t} );\n}\n\nexport async function whenElementorReady< T >(\n\tfn: () => T | Promise< T >,\n\toptions: WaitForElementorOptions = DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS\n): Promise< T > {\n\tawait waitForElementor( options );\n\tawait waitForElementorEditor();\n\treturn await fn();\n}\n","import { ensureElementorFrontend, isGutenbergEditor } from './editor-detection';\nimport { get$e, getElementor, getElementorFrontend, getWp } from './utils';\n\ninterface GutenbergBlockEditorDispatch {\n\tupdateBlockAttributes: ( clientId: string, attributes: Record< string, unknown > ) => void;\n}\n\ninterface GutenbergBlockEditorSelect {\n\tgetBlock: ( clientId: string ) => { name: string } | null;\n}\n\ninterface GutenbergBlock {\n\tname: string;\n}\n\nexport function injectElementCSS( elementId: string, css: string ): void {\n\tconst style = document.createElement( 'style' );\n\tstyle.id = elementId;\n\tstyle.appendChild( document.createTextNode( css ) );\n\n\tensureElementorFrontend();\n\tconst frontend = getElementorFrontend() as { elements: { $body: HTMLElement[] } } | undefined;\n\tif ( frontend ) {\n\t\tfrontend.elements.$body[ 0 ].appendChild( style );\n\t}\n}\n\nexport function removeElementCSS( elementId: string ): void {\n\tensureElementorFrontend();\n\tconst frontend = getElementorFrontend() as { elements: { $body: HTMLElement[] } } | undefined;\n\tif ( ! frontend ) {\n\t\treturn;\n\t}\n\n\tconst bodyElement = frontend.elements.$body[ 0 ];\n\tconst styleTags = bodyElement.querySelectorAll( `#${ CSS.escape( elementId ) }` );\n\n\tif ( styleTags?.length > 0 ) {\n\t\tstyleTags.forEach( ( tag: Element ) => {\n\t\t\tbodyElement.removeChild( tag );\n\t\t} );\n\t}\n}\n\nexport async function updateElementSettings( {\n\tid,\n\tsettings,\n}: {\n\tid: string;\n\tsettings: Record< string, unknown >;\n} ): Promise< unknown > {\n\tconst containerToUpdateSettings = getElementor()?.getContainer( id );\n\tif ( ! containerToUpdateSettings ) {\n\t\tthrow new Error( `Element with ID \"${ id }\" not found.` );\n\t}\n\n\tconst updateResult = await get$e()?.run( 'document/elements/settings', {\n\t\tcontainer: containerToUpdateSettings,\n\t\tsettings,\n\t\toptions: {\n\t\t\texternal: true,\n\t\t\trender: true,\n\t\t},\n\t} );\n\n\tconst frontend = getElementorFrontend() as { elements: { $body: { resize: () => void } } } | undefined;\n\tfrontend?.elements.$body.resize();\n\n\treturn updateResult;\n}\n\nexport function getElementSettings( id: string ): unknown {\n\tconst container = getElementor()?.getContainer( id );\n\tif ( ! container ) {\n\t\tthrow new Error( `Element with ID \"${ id }\" not found.` );\n\t}\n\treturn container.settings;\n}\n\nexport function getGutenbergBlockEditorApis(): {\n\tblockEditorDispatch: GutenbergBlockEditorDispatch;\n\tblockEditorSelect: GutenbergBlockEditorSelect;\n} {\n\tconst wp = getWp();\n\tif ( ! isGutenbergEditor() || ! wp ) {\n\t\tthrow new Error( 'WordPress editor API is not available' );\n\t}\n\n\tconst blockEditorDispatch = wp.data.dispatch( 'core/block-editor' ) as unknown as GutenbergBlockEditorDispatch;\n\tconst blockEditorSelect = wp.data.select( 'core/block-editor' ) as unknown as GutenbergBlockEditorSelect;\n\n\tif ( ! blockEditorDispatch || ! blockEditorSelect ) {\n\t\tthrow new Error( 'Block editor API is not available' );\n\t}\n\n\treturn { blockEditorDispatch, blockEditorSelect };\n}\n\nexport function validateAndGetGutenbergBlock(\n\tblockEditorSelect: GutenbergBlockEditorSelect,\n\tblockId: string\n): GutenbergBlock {\n\tconst block = blockEditorSelect.getBlock( blockId );\n\tif ( ! block ) {\n\t\tthrow new Error( `Block with ID \"${ blockId }\" not found` );\n\t}\n\treturn block;\n}\n\nexport function updateGutenbergBlockAttributes(\n\tblockId: string,\n\tattributes: Record< string, unknown >\n): { blockId: string; blockName: string; updatedAttributes: string[] } {\n\tconst { blockEditorDispatch, blockEditorSelect } = getGutenbergBlockEditorApis();\n\tconst block = validateAndGetGutenbergBlock( blockEditorSelect, blockId );\n\n\tblockEditorDispatch.updateBlockAttributes( blockId, attributes );\n\n\treturn {\n\t\tblockId,\n\t\tblockName: block.name,\n\t\tupdatedAttributes: Object.keys( attributes ),\n\t};\n}\n\nexport function extractElementImageData(\n\ttargetElementId: string,\n\tfallbackImageId = '',\n\tfallbackImageUrl = ''\n): { imageId: string; imageUrl: string } {\n\tlet extractedImageId = fallbackImageId;\n\tlet extractedImageUrl = fallbackImageUrl;\n\n\tif ( targetElementId && ( ! extractedImageId || ! extractedImageUrl ) ) {\n\t\tconst targetContainer = getElementor()?.getContainer?.( targetElementId );\n\t\tif ( targetContainer ) {\n\t\t\tconst imageData = targetContainer.settings.get( 'image' );\n\t\t\tif ( imageData && typeof imageData === 'object' ) {\n\t\t\t\tconst imageObj = imageData as { id?: string | number; url?: string };\n\t\t\t\textractedImageId = extractedImageId || imageObj.id?.toString() || '';\n\t\t\t\textractedImageUrl = extractedImageUrl || imageObj.url || '';\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\timageId: extractedImageId,\n\t\timageUrl: extractedImageUrl,\n\t};\n}\n\nexport function isSelectAllCheckbox( input: HTMLInputElement ): boolean {\n\tif ( ( input.id && input.id.includes( 'select-all' ) ) || ( input.name && input.name.includes( 'select-all' ) ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","import type { WpApiSettings } from './types';\nimport { getAjaxUrl, getJQuery, getWpApiSettings } from './utils';\n\ntype HeartbeatTickData = {\n\tangie_nonce?: string;\n};\n\nlet isNonceRefreshInitialized = false;\nlet nonceRefreshPromise: Promise< string > | null = null;\n\nexport function initNonceRefresh(): void {\n\tconst jQuery = getJQuery();\n\tconst wpApiSettings = getWpApiSettings();\n\tif ( isNonceRefreshInitialized || typeof jQuery === 'undefined' || ! wpApiSettings ) {\n\t\treturn;\n\t}\n\n\tisNonceRefreshInitialized = true;\n\n\tjQuery?.( document ).on( 'heartbeat-tick.angieNonceRefresh', ( _event: unknown, data: unknown ) => {\n\t\ttry {\n\t\t\tconst tickData = data as HeartbeatTickData;\n\t\t\tconst currentSettings = getWpApiSettings() as WpApiSettings | undefined;\n\t\t\tif ( tickData.angie_nonce && currentSettings && currentSettings.nonce !== tickData.angie_nonce ) {\n\t\t\t\tcurrentSettings.nonce = tickData.angie_nonce;\n\t\t\t}\n\t\t} catch ( error ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error( 'Failed to refresh nonce:', error );\n\t\t}\n\t} );\n}\n\nexport async function refreshNonce(): Promise< string > {\n\tif ( nonceRefreshPromise ) {\n\t\treturn nonceRefreshPromise;\n\t}\n\n\tnonceRefreshPromise = fetchFreshNonce();\n\n\ttry {\n\t\treturn await nonceRefreshPromise;\n\t} finally {\n\t\tnonceRefreshPromise = null;\n\t}\n}\n\nasync function fetchFreshNonce(): Promise< string > {\n\tconst ajaxUrl = new URL( getAjaxUrl() || '/wp-admin/admin-ajax.php', window.location.origin );\n\tajaxUrl.searchParams.set( 'action', 'rest-nonce' );\n\tconst response = await fetch( ajaxUrl.toString(), {\n\t\tcredentials: 'same-origin',\n\t} );\n\n\tif ( ! response.ok ) {\n\t\tthrow new Error( `Failed to refresh nonce: HTTP ${ response.status }` );\n\t}\n\n\tconst nonce = await response.text();\n\n\tif ( ! nonce || nonce === '0' ) {\n\t\tthrow new Error( 'Session expired — received invalid nonce' );\n\t}\n\n\tconst wpApiSettings = getWpApiSettings() as WpApiSettings | undefined;\n\tif ( ! wpApiSettings ) {\n\t\tthrow new Error( 'wpApiSettings not available — cannot refresh nonce' );\n\t}\n\n\twpApiSettings.nonce = nonce;\n\treturn nonce;\n}\n\nexport function isNonceError( status: number, responseText: string ): boolean {\n\treturn status === 403 && responseText.includes( 'rest_cookie_invalid_nonce' );\n}\n","import { isNonceError, refreshNonce } from './nonce-refresh';\nimport { getWpApiSettings } from './utils';\n\ntype WpApiResponse = unknown;\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS';\n\ntype CallWpApiOptions = {\n\tbinaryData?: ArrayBufferLike;\n\tcustomHeaders?: Record< string, string >;\n};\n\ntype CallWpApiResult< T > = {\n\tdata: T;\n\ttotalItems?: number;\n\ttotalPages?: number;\n};\n\nexport async function callWpApi< T = WpApiResponse >(\n\tendpoint: string,\n\tmethod: HttpMethod,\n\tdata?: Record< string, unknown >,\n\toptions?: CallWpApiOptions\n): Promise< CallWpApiResult< T > > {\n\treturn executeWpApiCall< T >( endpoint, method, data, options, true );\n}\n\nasync function executeWpApiCall< T = WpApiResponse >(\n\tendpoint: string,\n\tmethod: HttpMethod,\n\tdata?: Record< string, unknown >,\n\toptions?: CallWpApiOptions,\n\tallowNonceRetry = false\n): Promise< CallWpApiResult< T > > {\n\tconst wpApiSettings = getWpApiSettings();\n\tif ( ! wpApiSettings?.nonce || ! wpApiSettings.root ) {\n\t\tthrow new Error( 'wpApiSettings not available' );\n\t}\n\n\tconst baseUrl = wpApiSettings.root;\n\tconst urlObject = new URL( baseUrl );\n\tconst endpointUrl = new URL( endpoint, baseUrl );\n\n\turlObject.searchParams.set( 'rest_route', endpointUrl.pathname );\n\n\tfor ( const [ key, value ] of endpointUrl.searchParams.entries() ) {\n\t\turlObject.searchParams.append( key, value );\n\t}\n\n\tconst url = urlObject.toString();\n\n\tconst headers: Record< string, string > = {\n\t\t'X-WP-Nonce': wpApiSettings.nonce,\n\t\t...( options?.customHeaders || {} ),\n\t};\n\n\tif ( ! options?.binaryData && ! options?.customHeaders?.[ 'Content-Type' ] ) {\n\t\theaders[ 'Content-Type' ] = 'application/json';\n\t}\n\n\tconst requestOptions: RequestInit = {\n\t\tmethod,\n\t\theaders,\n\t\tcredentials: 'same-origin',\n\t};\n\n\tif ( options?.binaryData ) {\n\t\trequestOptions.body = options.binaryData as ArrayBuffer;\n\t} else if ( data && ( method === 'POST' || method === 'PUT' || method === 'PATCH' ) ) {\n\t\trequestOptions.body = JSON.stringify( data );\n\t}\n\n\tconst response = await fetch( url, requestOptions );\n\n\tif ( ! response.ok ) {\n\t\tconst responseText = await response.text();\n\n\t\tif ( allowNonceRetry && isNonceError( response.status, responseText ) ) {\n\t\t\tawait refreshNonce();\n\t\t\treturn executeWpApiCall< T >( endpoint, method, data, options, false );\n\t\t}\n\n\t\tthrow new Error( `HTTP error ${ response.status }: ${ responseText }` );\n\t}\n\n\tconst responseText = await response.text();\n\tconst json = extractJSONFromResponse( responseText );\n\n\tif ( json === null ) {\n\t\tthrow new Error( `Invalid response: no JSON found in: ${ responseText.substring( 0, 200 ) }` );\n\t}\n\n\tconst jsonObj = json as { success?: boolean };\n\tif ( jsonObj?.success !== undefined && ! jsonObj.success ) {\n\t\tthrow new Error( `API errors: ${ JSON.stringify( json ) }` );\n\t}\n\n\tconst totalItemsHeader = response.headers.get( 'X-WP-Total' );\n\tconst totalPagesHeader = response.headers.get( 'X-WP-TotalPages' );\n\tconst totalItems: number | undefined = totalItemsHeader ? parseInt( totalItemsHeader, 10 ) : undefined;\n\tconst totalPages: number | undefined = totalPagesHeader ? parseInt( totalPagesHeader, 10 ) : undefined;\n\n\treturn {\n\t\tdata: json as T,\n\t\ttotalItems,\n\t\ttotalPages,\n\t};\n}\n\nexport function extractJSONFromResponse( responseText: string ): unknown {\n\tconst objectStart = responseText.indexOf( '{' );\n\tconst arrayStart = responseText.indexOf( '[' );\n\n\tlet startIndex = -1;\n\tlet isArray = false;\n\n\tif ( objectStart === -1 && arrayStart === -1 ) {\n\t\treturn null;\n\t}\n\n\tif ( objectStart === -1 ) {\n\t\tstartIndex = arrayStart;\n\t\tisArray = true;\n\t} else if ( arrayStart === -1 ) {\n\t\tstartIndex = objectStart;\n\t\tisArray = false;\n\t} else if ( arrayStart < objectStart ) {\n\t\tstartIndex = arrayStart;\n\t\tisArray = true;\n\t} else {\n\t\tstartIndex = objectStart;\n\t\tisArray = false;\n\t}\n\n\tlet delimiterCount = 0;\n\tlet endIndex = -1;\n\tconst openChar = isArray ? '[' : '{';\n\tconst closeChar = isArray ? ']' : '}';\n\n\tfor ( let i = startIndex; i < responseText.length; i++ ) {\n\t\tif ( responseText[ i ] === openChar ) {\n\t\t\tdelimiterCount++;\n\t\t} else if ( responseText[ i ] === closeChar ) {\n\t\t\tdelimiterCount--;\n\t\t\tif ( delimiterCount === 0 ) {\n\t\t\t\tendIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( endIndex === -1 ) {\n\t\treturn null;\n\t}\n\n\tconst jsonString = responseText.substring( startIndex, endIndex + 1 );\n\n\ttry {\n\t\treturn JSON.parse( jsonString );\n\t} catch {\n\t\treturn null;\n\t}\n}\n"],"mappings":"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","names":["responseText"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/editor-detection.ts","../src/elements.ts","../src/nonce-refresh.ts","../src/rest-client.ts","../src/validation-utils.ts"],"sourcesContent":["export {\n\tisGutenbergEditor,\n\tisElementorEditor,\n\tisElementorAIActive,\n\thasGutenbergUI,\n\tensureElementorFrontend,\n\tisElementorEditorReady,\n\twaitForElementorEditor,\n\twaitForElementor,\n\twhenElementorReady,\n} from './editor-detection';\n\nexport {\n\tinjectElementCSS,\n\tremoveElementCSS,\n\tupdateElementSettings,\n\tgetElementSettings,\n\tgetGutenbergBlockEditorApis,\n\tvalidateAndGetGutenbergBlock,\n\tupdateGutenbergBlockAttributes,\n\textractElementImageData,\n\tisSelectAllCheckbox,\n} from './elements';\n\nexport { callWpApi, extractJSONFromResponse } from './rest-client';\nexport { initNonceRefresh, refreshNonce, isNonceError } from './nonce-refresh';\nexport { requireConfirmationMessage } from './validation-utils';\n\nexport type {\n\tElementorChannels,\n\tElementorCommandsInstance,\n\tElementorCommonInstance,\n\tElementorContainer,\n\tElementorDocument,\n\tElementorFrontendInstance,\n\tElementorInstance,\n\tJQuery,\n\tWpApiSettings,\n\tWpDataInstance,\n} from './types';\n\nexport {\n\tget$e,\n\tgetAjaxUrl,\n\tgetElementor,\n\tgetElementorAiConfig,\n\tgetElementorCommon,\n\tgetElementorFrontend,\n\tgetJQuery,\n\tgetWp,\n\tgetWpApiSettings,\n} from './utils';\n","import type {\n\tElementorCommandsInstance,\n\tElementorCommonInstance,\n\tElementorFrontendInstance,\n\tElementorInstance,\n\tWpApiSettings,\n\tWpDataInstance,\n} from './types';\n\ninterface McpWindow {\n\telementor?: ElementorInstance;\n\telementorFrontend?: ElementorFrontendInstance;\n\t$e?: ElementorCommandsInstance;\n\telementorCommon?: ElementorCommonInstance;\n\twpApiSettings?: WpApiSettings;\n\tajaxurl?: string;\n\twp?: {\n\t\tdata: WpDataInstance;\n\t};\n\tjQuery?: ( selector: unknown ) => {\n\t\ton: ( event: string, callback: ( event: unknown, data: unknown ) => void ) => void;\n\t\tget?: ( index: number ) => HTMLElement;\n\t};\n\tElementorAiConfig?: Record< string, unknown >;\n}\n\nexport const getElementor = (): ElementorInstance | undefined => ( window as unknown as McpWindow ).elementor;\n\nexport const getElementorFrontend = (): ElementorFrontendInstance | undefined =>\n\t( window as unknown as McpWindow ).elementorFrontend;\n\nexport const get$e = (): ElementorCommandsInstance | undefined => ( window as unknown as McpWindow ).$e;\n\nexport const getElementorCommon = (): ElementorCommonInstance | undefined =>\n\t( window as unknown as McpWindow ).elementorCommon;\n\nexport const getWpApiSettings = (): WpApiSettings | undefined => ( window as unknown as McpWindow ).wpApiSettings;\n\nexport const getAjaxUrl = (): string | undefined => ( window as unknown as McpWindow ).ajaxurl;\n\nexport const getWp = (): { data: WpDataInstance } | undefined => ( window as unknown as McpWindow ).wp;\n\nexport const getJQuery = (): McpWindow[ 'jQuery' ] => ( window as unknown as McpWindow ).jQuery;\n\nexport const getElementorAiConfig = (): Record< string, unknown > | undefined =>\n\t( window as unknown as McpWindow ).ElementorAiConfig;\n","import { get$e, getElementor, getElementorAiConfig, getElementorFrontend, getWp } from './utils';\n\ntype WaitForElementorOptions = {\n\tmaxRetries: number;\n\tretryInterval?: number;\n\tcheckFn: () => boolean;\n};\n\nconst ELEMENTOR_LOAD_TIMEOUT_MS = 5000;\nconst ELEMENTOR_CHECK_INTERVAL_MS = 100;\nconst DEFAULT_MAX_RETRIES = ELEMENTOR_LOAD_TIMEOUT_MS / ELEMENTOR_CHECK_INTERVAL_MS;\n\nconst DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS: WaitForElementorOptions = {\n\tmaxRetries: DEFAULT_MAX_RETRIES,\n\tretryInterval: ELEMENTOR_CHECK_INTERVAL_MS,\n\tcheckFn: () => !! ( getElementor() && get$e() ),\n};\n\nexport function isGutenbergEditor(): boolean {\n\treturn getWp()?.data?.select( 'core/editor' ) !== undefined;\n}\n\nexport function isElementorEditor(): boolean {\n\tconst params = new URLSearchParams( window.location.search );\n\tfor ( const [ , value ] of params.entries() ) {\n\t\tif ( value.includes( 'elementor' ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function isElementorAIActive(): boolean {\n\treturn !! getElementorAiConfig();\n}\n\nexport function hasGutenbergUI(): boolean {\n\treturn !! document.querySelector( '.edit-post-header-toolbar' );\n}\n\nexport function ensureElementorFrontend(): void {\n\tconst frontend = getElementorFrontend() as { elements?: { $body?: unknown } } | undefined;\n\tif ( ! frontend?.elements?.$body ) {\n\t\tthrow new Error( 'elementorFrontend or its required components not available' );\n\t}\n}\n\nexport function isElementorEditorReady(): boolean {\n\treturn !! get$e()?.components.get( 'panel' );\n}\n\nexport function waitForElementorEditor(): Promise< void > {\n\treturn new Promise( ( resolve ) => {\n\t\tif ( isElementorEditorReady() ) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\n\t\tconst checkReady = () => {\n\t\t\tif ( isElementorEditorReady() ) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\tsetTimeout( checkReady, 100 );\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener(\n\t\t\t'DOMContentLoaded',\n\t\t\t() => {\n\t\t\t\tcheckReady();\n\t\t\t},\n\t\t\t{\n\t\t\t\tonce: true,\n\t\t\t}\n\t\t);\n\t} );\n}\n\nexport function waitForElementor(\n\toptions: WaitForElementorOptions = DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS\n): Promise< void > {\n\tconst { maxRetries, retryInterval, checkFn } = options;\n\n\treturn new Promise( ( resolve, reject ) => {\n\t\tlet attempts = 0;\n\n\t\tconst check = () => {\n\t\t\tif ( checkFn() ) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tattempts++;\n\n\t\t\tif ( attempts >= maxRetries ) {\n\t\t\t\treject( new Error( `Elementor not loaded after ${ maxRetries } attempts` ) );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetTimeout( check, retryInterval );\n\t\t};\n\n\t\tcheck();\n\t} );\n}\n\nexport async function whenElementorReady< T >(\n\tfn: () => T | Promise< T >,\n\toptions: WaitForElementorOptions = DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS\n): Promise< T > {\n\tawait waitForElementor( options );\n\tawait waitForElementorEditor();\n\treturn await fn();\n}\n","import { ensureElementorFrontend, isGutenbergEditor } from './editor-detection';\nimport { get$e, getElementor, getElementorFrontend, getWp } from './utils';\n\ninterface GutenbergBlockEditorDispatch {\n\tupdateBlockAttributes: ( clientId: string, attributes: Record< string, unknown > ) => void;\n}\n\ninterface GutenbergBlockEditorSelect {\n\tgetBlock: ( clientId: string ) => { name: string } | null;\n}\n\ninterface GutenbergBlock {\n\tname: string;\n}\n\nexport function injectElementCSS( elementId: string, css: string ): void {\n\tconst style = document.createElement( 'style' );\n\tstyle.id = elementId;\n\tstyle.appendChild( document.createTextNode( css ) );\n\n\tensureElementorFrontend();\n\tconst frontend = getElementorFrontend() as { elements: { $body: HTMLElement[] } } | undefined;\n\tif ( frontend ) {\n\t\tfrontend.elements.$body[ 0 ].appendChild( style );\n\t}\n}\n\nexport function removeElementCSS( elementId: string ): void {\n\tensureElementorFrontend();\n\tconst frontend = getElementorFrontend() as { elements: { $body: HTMLElement[] } } | undefined;\n\tif ( ! frontend ) {\n\t\treturn;\n\t}\n\n\tconst bodyElement = frontend.elements.$body[ 0 ];\n\tconst styleTags = bodyElement.querySelectorAll( `#${ CSS.escape( elementId ) }` );\n\n\tif ( styleTags?.length > 0 ) {\n\t\tstyleTags.forEach( ( tag: Element ) => {\n\t\t\tbodyElement.removeChild( tag );\n\t\t} );\n\t}\n}\n\nexport async function updateElementSettings( {\n\tid,\n\tsettings,\n}: {\n\tid: string;\n\tsettings: Record< string, unknown >;\n} ): Promise< unknown > {\n\tconst containerToUpdateSettings = getElementor()?.getContainer( id );\n\tif ( ! containerToUpdateSettings ) {\n\t\tthrow new Error( `Element with ID \"${ id }\" not found.` );\n\t}\n\n\tconst updateResult = await get$e()?.run( 'document/elements/settings', {\n\t\tcontainer: containerToUpdateSettings,\n\t\tsettings,\n\t\toptions: {\n\t\t\texternal: true,\n\t\t\trender: true,\n\t\t},\n\t} );\n\n\tconst frontend = getElementorFrontend() as { elements: { $body: { resize: () => void } } } | undefined;\n\tfrontend?.elements.$body.resize();\n\n\treturn updateResult;\n}\n\nexport function getElementSettings( id: string ): unknown {\n\tconst container = getElementor()?.getContainer( id );\n\tif ( ! container ) {\n\t\tthrow new Error( `Element with ID \"${ id }\" not found.` );\n\t}\n\treturn container.settings;\n}\n\nexport function getGutenbergBlockEditorApis(): {\n\tblockEditorDispatch: GutenbergBlockEditorDispatch;\n\tblockEditorSelect: GutenbergBlockEditorSelect;\n} {\n\tconst wp = getWp();\n\tif ( ! isGutenbergEditor() || ! wp ) {\n\t\tthrow new Error( 'WordPress editor API is not available' );\n\t}\n\n\tconst blockEditorDispatch = wp.data.dispatch( 'core/block-editor' ) as unknown as GutenbergBlockEditorDispatch;\n\tconst blockEditorSelect = wp.data.select( 'core/block-editor' ) as unknown as GutenbergBlockEditorSelect;\n\n\tif ( ! blockEditorDispatch || ! blockEditorSelect ) {\n\t\tthrow new Error( 'Block editor API is not available' );\n\t}\n\n\treturn { blockEditorDispatch, blockEditorSelect };\n}\n\nexport function validateAndGetGutenbergBlock(\n\tblockEditorSelect: GutenbergBlockEditorSelect,\n\tblockId: string\n): GutenbergBlock {\n\tconst block = blockEditorSelect.getBlock( blockId );\n\tif ( ! block ) {\n\t\tthrow new Error( `Block with ID \"${ blockId }\" not found` );\n\t}\n\treturn block;\n}\n\nexport function updateGutenbergBlockAttributes(\n\tblockId: string,\n\tattributes: Record< string, unknown >\n): { blockId: string; blockName: string; updatedAttributes: string[] } {\n\tconst { blockEditorDispatch, blockEditorSelect } = getGutenbergBlockEditorApis();\n\tconst block = validateAndGetGutenbergBlock( blockEditorSelect, blockId );\n\n\tblockEditorDispatch.updateBlockAttributes( blockId, attributes );\n\n\treturn {\n\t\tblockId,\n\t\tblockName: block.name,\n\t\tupdatedAttributes: Object.keys( attributes ),\n\t};\n}\n\nexport function extractElementImageData(\n\ttargetElementId: string,\n\tfallbackImageId = '',\n\tfallbackImageUrl = ''\n): { imageId: string; imageUrl: string } {\n\tlet extractedImageId = fallbackImageId;\n\tlet extractedImageUrl = fallbackImageUrl;\n\n\tif ( targetElementId && ( ! extractedImageId || ! extractedImageUrl ) ) {\n\t\tconst targetContainer = getElementor()?.getContainer?.( targetElementId );\n\t\tif ( targetContainer ) {\n\t\t\tconst imageData = targetContainer.settings.get( 'image' );\n\t\t\tif ( imageData && typeof imageData === 'object' ) {\n\t\t\t\tconst imageObj = imageData as { id?: string | number; url?: string };\n\t\t\t\textractedImageId = extractedImageId || imageObj.id?.toString() || '';\n\t\t\t\textractedImageUrl = extractedImageUrl || imageObj.url || '';\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\timageId: extractedImageId,\n\t\timageUrl: extractedImageUrl,\n\t};\n}\n\nexport function isSelectAllCheckbox( input: HTMLInputElement ): boolean {\n\tif ( ( input.id && input.id.includes( 'select-all' ) ) || ( input.name && input.name.includes( 'select-all' ) ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","import type { WpApiSettings } from './types';\nimport { getAjaxUrl, getJQuery, getWpApiSettings } from './utils';\n\ntype HeartbeatTickData = {\n\tangie_nonce?: string;\n};\n\nlet isNonceRefreshInitialized = false;\nlet nonceRefreshPromise: Promise< string > | null = null;\n\nexport function initNonceRefresh(): void {\n\tconst jQuery = getJQuery();\n\tconst wpApiSettings = getWpApiSettings();\n\tif ( isNonceRefreshInitialized || typeof jQuery === 'undefined' || ! wpApiSettings ) {\n\t\treturn;\n\t}\n\n\tisNonceRefreshInitialized = true;\n\n\tjQuery?.( document ).on( 'heartbeat-tick.angieNonceRefresh', ( _event: unknown, data: unknown ) => {\n\t\ttry {\n\t\t\tconst tickData = data as HeartbeatTickData;\n\t\t\tconst currentSettings = getWpApiSettings() as WpApiSettings | undefined;\n\t\t\tif ( tickData.angie_nonce && currentSettings && currentSettings.nonce !== tickData.angie_nonce ) {\n\t\t\t\tcurrentSettings.nonce = tickData.angie_nonce;\n\t\t\t}\n\t\t} catch ( error ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error( 'Failed to refresh nonce:', error );\n\t\t}\n\t} );\n}\n\nexport async function refreshNonce(): Promise< string > {\n\tif ( nonceRefreshPromise ) {\n\t\treturn nonceRefreshPromise;\n\t}\n\n\tnonceRefreshPromise = fetchFreshNonce();\n\n\ttry {\n\t\treturn await nonceRefreshPromise;\n\t} finally {\n\t\tnonceRefreshPromise = null;\n\t}\n}\n\nasync function fetchFreshNonce(): Promise< string > {\n\tconst ajaxUrl = new URL( getAjaxUrl() || '/wp-admin/admin-ajax.php', window.location.origin );\n\tajaxUrl.searchParams.set( 'action', 'rest-nonce' );\n\tconst response = await fetch( ajaxUrl.toString(), {\n\t\tcredentials: 'same-origin',\n\t} );\n\n\tif ( ! response.ok ) {\n\t\tthrow new Error( `Failed to refresh nonce: HTTP ${ response.status }` );\n\t}\n\n\tconst nonce = await response.text();\n\n\tif ( ! nonce || nonce === '0' ) {\n\t\tthrow new Error( 'Session expired — received invalid nonce' );\n\t}\n\n\tconst wpApiSettings = getWpApiSettings() as WpApiSettings | undefined;\n\tif ( ! wpApiSettings ) {\n\t\tthrow new Error( 'wpApiSettings not available — cannot refresh nonce' );\n\t}\n\n\twpApiSettings.nonce = nonce;\n\treturn nonce;\n}\n\nexport function isNonceError( status: number, responseText: string ): boolean {\n\treturn status === 403 && responseText.includes( 'rest_cookie_invalid_nonce' );\n}\n","import { isNonceError, refreshNonce } from './nonce-refresh';\nimport { getWpApiSettings } from './utils';\n\ntype WpApiResponse = unknown;\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS';\n\ntype CallWpApiOptions = {\n\tbinaryData?: ArrayBufferLike;\n\tcustomHeaders?: Record< string, string >;\n};\n\ntype CallWpApiResult< T > = {\n\tdata: T;\n\ttotalItems?: number;\n\ttotalPages?: number;\n};\n\nexport async function callWpApi< T = WpApiResponse >(\n\tendpoint: string,\n\tmethod: HttpMethod,\n\tdata?: Record< string, unknown >,\n\toptions?: CallWpApiOptions\n): Promise< CallWpApiResult< T > > {\n\treturn executeWpApiCall< T >( endpoint, method, data, options, true );\n}\n\nasync function executeWpApiCall< T = WpApiResponse >(\n\tendpoint: string,\n\tmethod: HttpMethod,\n\tdata?: Record< string, unknown >,\n\toptions?: CallWpApiOptions,\n\tallowNonceRetry = false\n): Promise< CallWpApiResult< T > > {\n\tconst wpApiSettings = getWpApiSettings();\n\tif ( ! wpApiSettings?.nonce || ! wpApiSettings.root ) {\n\t\tthrow new Error( 'wpApiSettings not available' );\n\t}\n\n\tconst baseUrl = wpApiSettings.root;\n\tconst urlObject = new URL( baseUrl );\n\tconst endpointUrl = new URL( endpoint, baseUrl );\n\n\turlObject.searchParams.set( 'rest_route', endpointUrl.pathname );\n\n\tfor ( const [ key, value ] of endpointUrl.searchParams.entries() ) {\n\t\turlObject.searchParams.append( key, value );\n\t}\n\n\tconst url = urlObject.toString();\n\n\tconst headers: Record< string, string > = {\n\t\t'X-WP-Nonce': wpApiSettings.nonce,\n\t\t...( options?.customHeaders || {} ),\n\t};\n\n\tif ( ! options?.binaryData && ! options?.customHeaders?.[ 'Content-Type' ] ) {\n\t\theaders[ 'Content-Type' ] = 'application/json';\n\t}\n\n\tconst requestOptions: RequestInit = {\n\t\tmethod,\n\t\theaders,\n\t\tcredentials: 'same-origin',\n\t};\n\n\tif ( options?.binaryData ) {\n\t\trequestOptions.body = options.binaryData as ArrayBuffer;\n\t} else if ( data && ( method === 'POST' || method === 'PUT' || method === 'PATCH' ) ) {\n\t\trequestOptions.body = JSON.stringify( data );\n\t}\n\n\tconst response = await fetch( url, requestOptions );\n\n\tif ( ! response.ok ) {\n\t\tconst responseText = await response.text();\n\n\t\tif ( allowNonceRetry && isNonceError( response.status, responseText ) ) {\n\t\t\tawait refreshNonce();\n\t\t\treturn executeWpApiCall< T >( endpoint, method, data, options, false );\n\t\t}\n\n\t\tthrow new Error( `HTTP error ${ response.status }: ${ responseText }` );\n\t}\n\n\tconst responseText = await response.text();\n\tconst json = extractJSONFromResponse( responseText );\n\n\tif ( json === null ) {\n\t\tthrow new Error( `Invalid response: no JSON found in: ${ responseText.substring( 0, 200 ) }` );\n\t}\n\n\tconst jsonObj = json as { success?: boolean };\n\tif ( jsonObj?.success !== undefined && ! jsonObj.success ) {\n\t\tthrow new Error( `API errors: ${ JSON.stringify( json ) }` );\n\t}\n\n\tconst totalItemsHeader = response.headers.get( 'X-WP-Total' );\n\tconst totalPagesHeader = response.headers.get( 'X-WP-TotalPages' );\n\tconst totalItems: number | undefined = totalItemsHeader ? parseInt( totalItemsHeader, 10 ) : undefined;\n\tconst totalPages: number | undefined = totalPagesHeader ? parseInt( totalPagesHeader, 10 ) : undefined;\n\n\treturn {\n\t\tdata: json as T,\n\t\ttotalItems,\n\t\ttotalPages,\n\t};\n}\n\nexport function extractJSONFromResponse( responseText: string ): unknown {\n\tconst objectStart = responseText.indexOf( '{' );\n\tconst arrayStart = responseText.indexOf( '[' );\n\n\tlet startIndex = -1;\n\tlet isArray = false;\n\n\tif ( objectStart === -1 && arrayStart === -1 ) {\n\t\treturn null;\n\t}\n\n\tif ( objectStart === -1 ) {\n\t\tstartIndex = arrayStart;\n\t\tisArray = true;\n\t} else if ( arrayStart === -1 ) {\n\t\tstartIndex = objectStart;\n\t\tisArray = false;\n\t} else if ( arrayStart < objectStart ) {\n\t\tstartIndex = arrayStart;\n\t\tisArray = true;\n\t} else {\n\t\tstartIndex = objectStart;\n\t\tisArray = false;\n\t}\n\n\tlet delimiterCount = 0;\n\tlet endIndex = -1;\n\tconst openChar = isArray ? '[' : '{';\n\tconst closeChar = isArray ? ']' : '}';\n\n\tfor ( let i = startIndex; i < responseText.length; i++ ) {\n\t\tif ( responseText[ i ] === openChar ) {\n\t\t\tdelimiterCount++;\n\t\t} else if ( responseText[ i ] === closeChar ) {\n\t\t\tdelimiterCount--;\n\t\t\tif ( delimiterCount === 0 ) {\n\t\t\t\tendIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( endIndex === -1 ) {\n\t\treturn null;\n\t}\n\n\tconst jsonString = responseText.substring( startIndex, endIndex + 1 );\n\n\ttry {\n\t\treturn JSON.parse( jsonString );\n\t} catch {\n\t\treturn null;\n\t}\n}\n","export function requireConfirmationMessage( confirmationMessage: string | undefined, context: string ): void {\n\tif ( ! confirmationMessage || confirmationMessage.trim() === '' ) {\n\t\tthrow new Error(\n\t\t\t`LLM Instructions: ${ context } changes require user confirmation. You MUST provide a confirmationMessage parameter explaining what will be changed and its impact.`\n\t\t);\n\t}\n}\n"],"mappings":"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","names":["responseText"]}
|
package/dist/index.mjs
CHANGED
|
@@ -366,6 +366,15 @@ function extractJSONFromResponse(responseText) {
|
|
|
366
366
|
return null;
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
|
+
|
|
370
|
+
// src/validation-utils.ts
|
|
371
|
+
function requireConfirmationMessage(confirmationMessage, context) {
|
|
372
|
+
if (!confirmationMessage || confirmationMessage.trim() === "") {
|
|
373
|
+
throw new Error(
|
|
374
|
+
`LLM Instructions: ${context} changes require user confirmation. You MUST provide a confirmationMessage parameter explaining what will be changed and its impact.`
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
369
378
|
export {
|
|
370
379
|
callWpApi,
|
|
371
380
|
ensureElementorFrontend,
|
|
@@ -393,6 +402,7 @@ export {
|
|
|
393
402
|
isSelectAllCheckbox,
|
|
394
403
|
refreshNonce,
|
|
395
404
|
removeElementCSS,
|
|
405
|
+
requireConfirmationMessage,
|
|
396
406
|
updateElementSettings,
|
|
397
407
|
updateGutenbergBlockAttributes,
|
|
398
408
|
validateAndGetGutenbergBlock,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/editor-detection.ts","../src/elements.ts","../src/nonce-refresh.ts","../src/rest-client.ts"],"sourcesContent":["import type {\n\tElementorCommandsInstance,\n\tElementorCommonInstance,\n\tElementorFrontendInstance,\n\tElementorInstance,\n\tWpApiSettings,\n\tWpDataInstance,\n} from './types';\n\ninterface McpWindow {\n\telementor?: ElementorInstance;\n\telementorFrontend?: ElementorFrontendInstance;\n\t$e?: ElementorCommandsInstance;\n\telementorCommon?: ElementorCommonInstance;\n\twpApiSettings?: WpApiSettings;\n\tajaxurl?: string;\n\twp?: {\n\t\tdata: WpDataInstance;\n\t};\n\tjQuery?: ( selector: unknown ) => {\n\t\ton: ( event: string, callback: ( event: unknown, data: unknown ) => void ) => void;\n\t\tget?: ( index: number ) => HTMLElement;\n\t};\n\tElementorAiConfig?: Record< string, unknown >;\n}\n\nexport const getElementor = (): ElementorInstance | undefined => ( window as unknown as McpWindow ).elementor;\n\nexport const getElementorFrontend = (): ElementorFrontendInstance | undefined =>\n\t( window as unknown as McpWindow ).elementorFrontend;\n\nexport const get$e = (): ElementorCommandsInstance | undefined => ( window as unknown as McpWindow ).$e;\n\nexport const getElementorCommon = (): ElementorCommonInstance | undefined =>\n\t( window as unknown as McpWindow ).elementorCommon;\n\nexport const getWpApiSettings = (): WpApiSettings | undefined => ( window as unknown as McpWindow ).wpApiSettings;\n\nexport const getAjaxUrl = (): string | undefined => ( window as unknown as McpWindow ).ajaxurl;\n\nexport const getWp = (): { data: WpDataInstance } | undefined => ( window as unknown as McpWindow ).wp;\n\nexport const getJQuery = (): McpWindow[ 'jQuery' ] => ( window as unknown as McpWindow ).jQuery;\n\nexport const getElementorAiConfig = (): Record< string, unknown > | undefined =>\n\t( window as unknown as McpWindow ).ElementorAiConfig;\n","import { get$e, getElementor, getElementorAiConfig, getElementorFrontend, getWp } from './utils';\n\ntype WaitForElementorOptions = {\n\tmaxRetries: number;\n\tretryInterval?: number;\n\tcheckFn: () => boolean;\n};\n\nconst ELEMENTOR_LOAD_TIMEOUT_MS = 5000;\nconst ELEMENTOR_CHECK_INTERVAL_MS = 100;\nconst DEFAULT_MAX_RETRIES = ELEMENTOR_LOAD_TIMEOUT_MS / ELEMENTOR_CHECK_INTERVAL_MS;\n\nconst DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS: WaitForElementorOptions = {\n\tmaxRetries: DEFAULT_MAX_RETRIES,\n\tretryInterval: ELEMENTOR_CHECK_INTERVAL_MS,\n\tcheckFn: () => !! ( getElementor() && get$e() ),\n};\n\nexport function isGutenbergEditor(): boolean {\n\treturn getWp()?.data?.select( 'core/editor' ) !== undefined;\n}\n\nexport function isElementorEditor(): boolean {\n\tconst params = new URLSearchParams( window.location.search );\n\tfor ( const [ , value ] of params.entries() ) {\n\t\tif ( value.includes( 'elementor' ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function isElementorAIActive(): boolean {\n\treturn !! getElementorAiConfig();\n}\n\nexport function hasGutenbergUI(): boolean {\n\treturn !! document.querySelector( '.edit-post-header-toolbar' );\n}\n\nexport function ensureElementorFrontend(): void {\n\tconst frontend = getElementorFrontend() as { elements?: { $body?: unknown } } | undefined;\n\tif ( ! frontend?.elements?.$body ) {\n\t\tthrow new Error( 'elementorFrontend or its required components not available' );\n\t}\n}\n\nexport function isElementorEditorReady(): boolean {\n\treturn !! get$e()?.components.get( 'panel' );\n}\n\nexport function waitForElementorEditor(): Promise< void > {\n\treturn new Promise( ( resolve ) => {\n\t\tif ( isElementorEditorReady() ) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\n\t\tconst checkReady = () => {\n\t\t\tif ( isElementorEditorReady() ) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\tsetTimeout( checkReady, 100 );\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener(\n\t\t\t'DOMContentLoaded',\n\t\t\t() => {\n\t\t\t\tcheckReady();\n\t\t\t},\n\t\t\t{\n\t\t\t\tonce: true,\n\t\t\t}\n\t\t);\n\t} );\n}\n\nexport function waitForElementor(\n\toptions: WaitForElementorOptions = DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS\n): Promise< void > {\n\tconst { maxRetries, retryInterval, checkFn } = options;\n\n\treturn new Promise( ( resolve, reject ) => {\n\t\tlet attempts = 0;\n\n\t\tconst check = () => {\n\t\t\tif ( checkFn() ) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tattempts++;\n\n\t\t\tif ( attempts >= maxRetries ) {\n\t\t\t\treject( new Error( `Elementor not loaded after ${ maxRetries } attempts` ) );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetTimeout( check, retryInterval );\n\t\t};\n\n\t\tcheck();\n\t} );\n}\n\nexport async function whenElementorReady< T >(\n\tfn: () => T | Promise< T >,\n\toptions: WaitForElementorOptions = DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS\n): Promise< T > {\n\tawait waitForElementor( options );\n\tawait waitForElementorEditor();\n\treturn await fn();\n}\n","import { ensureElementorFrontend, isGutenbergEditor } from './editor-detection';\nimport { get$e, getElementor, getElementorFrontend, getWp } from './utils';\n\ninterface GutenbergBlockEditorDispatch {\n\tupdateBlockAttributes: ( clientId: string, attributes: Record< string, unknown > ) => void;\n}\n\ninterface GutenbergBlockEditorSelect {\n\tgetBlock: ( clientId: string ) => { name: string } | null;\n}\n\ninterface GutenbergBlock {\n\tname: string;\n}\n\nexport function injectElementCSS( elementId: string, css: string ): void {\n\tconst style = document.createElement( 'style' );\n\tstyle.id = elementId;\n\tstyle.appendChild( document.createTextNode( css ) );\n\n\tensureElementorFrontend();\n\tconst frontend = getElementorFrontend() as { elements: { $body: HTMLElement[] } } | undefined;\n\tif ( frontend ) {\n\t\tfrontend.elements.$body[ 0 ].appendChild( style );\n\t}\n}\n\nexport function removeElementCSS( elementId: string ): void {\n\tensureElementorFrontend();\n\tconst frontend = getElementorFrontend() as { elements: { $body: HTMLElement[] } } | undefined;\n\tif ( ! frontend ) {\n\t\treturn;\n\t}\n\n\tconst bodyElement = frontend.elements.$body[ 0 ];\n\tconst styleTags = bodyElement.querySelectorAll( `#${ CSS.escape( elementId ) }` );\n\n\tif ( styleTags?.length > 0 ) {\n\t\tstyleTags.forEach( ( tag: Element ) => {\n\t\t\tbodyElement.removeChild( tag );\n\t\t} );\n\t}\n}\n\nexport async function updateElementSettings( {\n\tid,\n\tsettings,\n}: {\n\tid: string;\n\tsettings: Record< string, unknown >;\n} ): Promise< unknown > {\n\tconst containerToUpdateSettings = getElementor()?.getContainer( id );\n\tif ( ! containerToUpdateSettings ) {\n\t\tthrow new Error( `Element with ID \"${ id }\" not found.` );\n\t}\n\n\tconst updateResult = await get$e()?.run( 'document/elements/settings', {\n\t\tcontainer: containerToUpdateSettings,\n\t\tsettings,\n\t\toptions: {\n\t\t\texternal: true,\n\t\t\trender: true,\n\t\t},\n\t} );\n\n\tconst frontend = getElementorFrontend() as { elements: { $body: { resize: () => void } } } | undefined;\n\tfrontend?.elements.$body.resize();\n\n\treturn updateResult;\n}\n\nexport function getElementSettings( id: string ): unknown {\n\tconst container = getElementor()?.getContainer( id );\n\tif ( ! container ) {\n\t\tthrow new Error( `Element with ID \"${ id }\" not found.` );\n\t}\n\treturn container.settings;\n}\n\nexport function getGutenbergBlockEditorApis(): {\n\tblockEditorDispatch: GutenbergBlockEditorDispatch;\n\tblockEditorSelect: GutenbergBlockEditorSelect;\n} {\n\tconst wp = getWp();\n\tif ( ! isGutenbergEditor() || ! wp ) {\n\t\tthrow new Error( 'WordPress editor API is not available' );\n\t}\n\n\tconst blockEditorDispatch = wp.data.dispatch( 'core/block-editor' ) as unknown as GutenbergBlockEditorDispatch;\n\tconst blockEditorSelect = wp.data.select( 'core/block-editor' ) as unknown as GutenbergBlockEditorSelect;\n\n\tif ( ! blockEditorDispatch || ! blockEditorSelect ) {\n\t\tthrow new Error( 'Block editor API is not available' );\n\t}\n\n\treturn { blockEditorDispatch, blockEditorSelect };\n}\n\nexport function validateAndGetGutenbergBlock(\n\tblockEditorSelect: GutenbergBlockEditorSelect,\n\tblockId: string\n): GutenbergBlock {\n\tconst block = blockEditorSelect.getBlock( blockId );\n\tif ( ! block ) {\n\t\tthrow new Error( `Block with ID \"${ blockId }\" not found` );\n\t}\n\treturn block;\n}\n\nexport function updateGutenbergBlockAttributes(\n\tblockId: string,\n\tattributes: Record< string, unknown >\n): { blockId: string; blockName: string; updatedAttributes: string[] } {\n\tconst { blockEditorDispatch, blockEditorSelect } = getGutenbergBlockEditorApis();\n\tconst block = validateAndGetGutenbergBlock( blockEditorSelect, blockId );\n\n\tblockEditorDispatch.updateBlockAttributes( blockId, attributes );\n\n\treturn {\n\t\tblockId,\n\t\tblockName: block.name,\n\t\tupdatedAttributes: Object.keys( attributes ),\n\t};\n}\n\nexport function extractElementImageData(\n\ttargetElementId: string,\n\tfallbackImageId = '',\n\tfallbackImageUrl = ''\n): { imageId: string; imageUrl: string } {\n\tlet extractedImageId = fallbackImageId;\n\tlet extractedImageUrl = fallbackImageUrl;\n\n\tif ( targetElementId && ( ! extractedImageId || ! extractedImageUrl ) ) {\n\t\tconst targetContainer = getElementor()?.getContainer?.( targetElementId );\n\t\tif ( targetContainer ) {\n\t\t\tconst imageData = targetContainer.settings.get( 'image' );\n\t\t\tif ( imageData && typeof imageData === 'object' ) {\n\t\t\t\tconst imageObj = imageData as { id?: string | number; url?: string };\n\t\t\t\textractedImageId = extractedImageId || imageObj.id?.toString() || '';\n\t\t\t\textractedImageUrl = extractedImageUrl || imageObj.url || '';\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\timageId: extractedImageId,\n\t\timageUrl: extractedImageUrl,\n\t};\n}\n\nexport function isSelectAllCheckbox( input: HTMLInputElement ): boolean {\n\tif ( ( input.id && input.id.includes( 'select-all' ) ) || ( input.name && input.name.includes( 'select-all' ) ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","import type { WpApiSettings } from './types';\nimport { getAjaxUrl, getJQuery, getWpApiSettings } from './utils';\n\ntype HeartbeatTickData = {\n\tangie_nonce?: string;\n};\n\nlet isNonceRefreshInitialized = false;\nlet nonceRefreshPromise: Promise< string > | null = null;\n\nexport function initNonceRefresh(): void {\n\tconst jQuery = getJQuery();\n\tconst wpApiSettings = getWpApiSettings();\n\tif ( isNonceRefreshInitialized || typeof jQuery === 'undefined' || ! wpApiSettings ) {\n\t\treturn;\n\t}\n\n\tisNonceRefreshInitialized = true;\n\n\tjQuery?.( document ).on( 'heartbeat-tick.angieNonceRefresh', ( _event: unknown, data: unknown ) => {\n\t\ttry {\n\t\t\tconst tickData = data as HeartbeatTickData;\n\t\t\tconst currentSettings = getWpApiSettings() as WpApiSettings | undefined;\n\t\t\tif ( tickData.angie_nonce && currentSettings && currentSettings.nonce !== tickData.angie_nonce ) {\n\t\t\t\tcurrentSettings.nonce = tickData.angie_nonce;\n\t\t\t}\n\t\t} catch ( error ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error( 'Failed to refresh nonce:', error );\n\t\t}\n\t} );\n}\n\nexport async function refreshNonce(): Promise< string > {\n\tif ( nonceRefreshPromise ) {\n\t\treturn nonceRefreshPromise;\n\t}\n\n\tnonceRefreshPromise = fetchFreshNonce();\n\n\ttry {\n\t\treturn await nonceRefreshPromise;\n\t} finally {\n\t\tnonceRefreshPromise = null;\n\t}\n}\n\nasync function fetchFreshNonce(): Promise< string > {\n\tconst ajaxUrl = new URL( getAjaxUrl() || '/wp-admin/admin-ajax.php', window.location.origin );\n\tajaxUrl.searchParams.set( 'action', 'rest-nonce' );\n\tconst response = await fetch( ajaxUrl.toString(), {\n\t\tcredentials: 'same-origin',\n\t} );\n\n\tif ( ! response.ok ) {\n\t\tthrow new Error( `Failed to refresh nonce: HTTP ${ response.status }` );\n\t}\n\n\tconst nonce = await response.text();\n\n\tif ( ! nonce || nonce === '0' ) {\n\t\tthrow new Error( 'Session expired — received invalid nonce' );\n\t}\n\n\tconst wpApiSettings = getWpApiSettings() as WpApiSettings | undefined;\n\tif ( ! wpApiSettings ) {\n\t\tthrow new Error( 'wpApiSettings not available — cannot refresh nonce' );\n\t}\n\n\twpApiSettings.nonce = nonce;\n\treturn nonce;\n}\n\nexport function isNonceError( status: number, responseText: string ): boolean {\n\treturn status === 403 && responseText.includes( 'rest_cookie_invalid_nonce' );\n}\n","import { isNonceError, refreshNonce } from './nonce-refresh';\nimport { getWpApiSettings } from './utils';\n\ntype WpApiResponse = unknown;\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS';\n\ntype CallWpApiOptions = {\n\tbinaryData?: ArrayBufferLike;\n\tcustomHeaders?: Record< string, string >;\n};\n\ntype CallWpApiResult< T > = {\n\tdata: T;\n\ttotalItems?: number;\n\ttotalPages?: number;\n};\n\nexport async function callWpApi< T = WpApiResponse >(\n\tendpoint: string,\n\tmethod: HttpMethod,\n\tdata?: Record< string, unknown >,\n\toptions?: CallWpApiOptions\n): Promise< CallWpApiResult< T > > {\n\treturn executeWpApiCall< T >( endpoint, method, data, options, true );\n}\n\nasync function executeWpApiCall< T = WpApiResponse >(\n\tendpoint: string,\n\tmethod: HttpMethod,\n\tdata?: Record< string, unknown >,\n\toptions?: CallWpApiOptions,\n\tallowNonceRetry = false\n): Promise< CallWpApiResult< T > > {\n\tconst wpApiSettings = getWpApiSettings();\n\tif ( ! wpApiSettings?.nonce || ! wpApiSettings.root ) {\n\t\tthrow new Error( 'wpApiSettings not available' );\n\t}\n\n\tconst baseUrl = wpApiSettings.root;\n\tconst urlObject = new URL( baseUrl );\n\tconst endpointUrl = new URL( endpoint, baseUrl );\n\n\turlObject.searchParams.set( 'rest_route', endpointUrl.pathname );\n\n\tfor ( const [ key, value ] of endpointUrl.searchParams.entries() ) {\n\t\turlObject.searchParams.append( key, value );\n\t}\n\n\tconst url = urlObject.toString();\n\n\tconst headers: Record< string, string > = {\n\t\t'X-WP-Nonce': wpApiSettings.nonce,\n\t\t...( options?.customHeaders || {} ),\n\t};\n\n\tif ( ! options?.binaryData && ! options?.customHeaders?.[ 'Content-Type' ] ) {\n\t\theaders[ 'Content-Type' ] = 'application/json';\n\t}\n\n\tconst requestOptions: RequestInit = {\n\t\tmethod,\n\t\theaders,\n\t\tcredentials: 'same-origin',\n\t};\n\n\tif ( options?.binaryData ) {\n\t\trequestOptions.body = options.binaryData as ArrayBuffer;\n\t} else if ( data && ( method === 'POST' || method === 'PUT' || method === 'PATCH' ) ) {\n\t\trequestOptions.body = JSON.stringify( data );\n\t}\n\n\tconst response = await fetch( url, requestOptions );\n\n\tif ( ! response.ok ) {\n\t\tconst responseText = await response.text();\n\n\t\tif ( allowNonceRetry && isNonceError( response.status, responseText ) ) {\n\t\t\tawait refreshNonce();\n\t\t\treturn executeWpApiCall< T >( endpoint, method, data, options, false );\n\t\t}\n\n\t\tthrow new Error( `HTTP error ${ response.status }: ${ responseText }` );\n\t}\n\n\tconst responseText = await response.text();\n\tconst json = extractJSONFromResponse( responseText );\n\n\tif ( json === null ) {\n\t\tthrow new Error( `Invalid response: no JSON found in: ${ responseText.substring( 0, 200 ) }` );\n\t}\n\n\tconst jsonObj = json as { success?: boolean };\n\tif ( jsonObj?.success !== undefined && ! jsonObj.success ) {\n\t\tthrow new Error( `API errors: ${ JSON.stringify( json ) }` );\n\t}\n\n\tconst totalItemsHeader = response.headers.get( 'X-WP-Total' );\n\tconst totalPagesHeader = response.headers.get( 'X-WP-TotalPages' );\n\tconst totalItems: number | undefined = totalItemsHeader ? parseInt( totalItemsHeader, 10 ) : undefined;\n\tconst totalPages: number | undefined = totalPagesHeader ? parseInt( totalPagesHeader, 10 ) : undefined;\n\n\treturn {\n\t\tdata: json as T,\n\t\ttotalItems,\n\t\ttotalPages,\n\t};\n}\n\nexport function extractJSONFromResponse( responseText: string ): unknown {\n\tconst objectStart = responseText.indexOf( '{' );\n\tconst arrayStart = responseText.indexOf( '[' );\n\n\tlet startIndex = -1;\n\tlet isArray = false;\n\n\tif ( objectStart === -1 && arrayStart === -1 ) {\n\t\treturn null;\n\t}\n\n\tif ( objectStart === -1 ) {\n\t\tstartIndex = arrayStart;\n\t\tisArray = true;\n\t} else if ( arrayStart === -1 ) {\n\t\tstartIndex = objectStart;\n\t\tisArray = false;\n\t} else if ( arrayStart < objectStart ) {\n\t\tstartIndex = arrayStart;\n\t\tisArray = true;\n\t} else {\n\t\tstartIndex = objectStart;\n\t\tisArray = false;\n\t}\n\n\tlet delimiterCount = 0;\n\tlet endIndex = -1;\n\tconst openChar = isArray ? '[' : '{';\n\tconst closeChar = isArray ? ']' : '}';\n\n\tfor ( let i = startIndex; i < responseText.length; i++ ) {\n\t\tif ( responseText[ i ] === openChar ) {\n\t\t\tdelimiterCount++;\n\t\t} else if ( responseText[ i ] === closeChar ) {\n\t\t\tdelimiterCount--;\n\t\t\tif ( delimiterCount === 0 ) {\n\t\t\t\tendIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( endIndex === -1 ) {\n\t\treturn null;\n\t}\n\n\tconst jsonString = responseText.substring( startIndex, endIndex + 1 );\n\n\ttry {\n\t\treturn JSON.parse( jsonString );\n\t} catch {\n\t\treturn null;\n\t}\n}\n"],"mappings":"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","names":["responseText"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/editor-detection.ts","../src/elements.ts","../src/nonce-refresh.ts","../src/rest-client.ts","../src/validation-utils.ts"],"sourcesContent":["import type {\n\tElementorCommandsInstance,\n\tElementorCommonInstance,\n\tElementorFrontendInstance,\n\tElementorInstance,\n\tWpApiSettings,\n\tWpDataInstance,\n} from './types';\n\ninterface McpWindow {\n\telementor?: ElementorInstance;\n\telementorFrontend?: ElementorFrontendInstance;\n\t$e?: ElementorCommandsInstance;\n\telementorCommon?: ElementorCommonInstance;\n\twpApiSettings?: WpApiSettings;\n\tajaxurl?: string;\n\twp?: {\n\t\tdata: WpDataInstance;\n\t};\n\tjQuery?: ( selector: unknown ) => {\n\t\ton: ( event: string, callback: ( event: unknown, data: unknown ) => void ) => void;\n\t\tget?: ( index: number ) => HTMLElement;\n\t};\n\tElementorAiConfig?: Record< string, unknown >;\n}\n\nexport const getElementor = (): ElementorInstance | undefined => ( window as unknown as McpWindow ).elementor;\n\nexport const getElementorFrontend = (): ElementorFrontendInstance | undefined =>\n\t( window as unknown as McpWindow ).elementorFrontend;\n\nexport const get$e = (): ElementorCommandsInstance | undefined => ( window as unknown as McpWindow ).$e;\n\nexport const getElementorCommon = (): ElementorCommonInstance | undefined =>\n\t( window as unknown as McpWindow ).elementorCommon;\n\nexport const getWpApiSettings = (): WpApiSettings | undefined => ( window as unknown as McpWindow ).wpApiSettings;\n\nexport const getAjaxUrl = (): string | undefined => ( window as unknown as McpWindow ).ajaxurl;\n\nexport const getWp = (): { data: WpDataInstance } | undefined => ( window as unknown as McpWindow ).wp;\n\nexport const getJQuery = (): McpWindow[ 'jQuery' ] => ( window as unknown as McpWindow ).jQuery;\n\nexport const getElementorAiConfig = (): Record< string, unknown > | undefined =>\n\t( window as unknown as McpWindow ).ElementorAiConfig;\n","import { get$e, getElementor, getElementorAiConfig, getElementorFrontend, getWp } from './utils';\n\ntype WaitForElementorOptions = {\n\tmaxRetries: number;\n\tretryInterval?: number;\n\tcheckFn: () => boolean;\n};\n\nconst ELEMENTOR_LOAD_TIMEOUT_MS = 5000;\nconst ELEMENTOR_CHECK_INTERVAL_MS = 100;\nconst DEFAULT_MAX_RETRIES = ELEMENTOR_LOAD_TIMEOUT_MS / ELEMENTOR_CHECK_INTERVAL_MS;\n\nconst DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS: WaitForElementorOptions = {\n\tmaxRetries: DEFAULT_MAX_RETRIES,\n\tretryInterval: ELEMENTOR_CHECK_INTERVAL_MS,\n\tcheckFn: () => !! ( getElementor() && get$e() ),\n};\n\nexport function isGutenbergEditor(): boolean {\n\treturn getWp()?.data?.select( 'core/editor' ) !== undefined;\n}\n\nexport function isElementorEditor(): boolean {\n\tconst params = new URLSearchParams( window.location.search );\n\tfor ( const [ , value ] of params.entries() ) {\n\t\tif ( value.includes( 'elementor' ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function isElementorAIActive(): boolean {\n\treturn !! getElementorAiConfig();\n}\n\nexport function hasGutenbergUI(): boolean {\n\treturn !! document.querySelector( '.edit-post-header-toolbar' );\n}\n\nexport function ensureElementorFrontend(): void {\n\tconst frontend = getElementorFrontend() as { elements?: { $body?: unknown } } | undefined;\n\tif ( ! frontend?.elements?.$body ) {\n\t\tthrow new Error( 'elementorFrontend or its required components not available' );\n\t}\n}\n\nexport function isElementorEditorReady(): boolean {\n\treturn !! get$e()?.components.get( 'panel' );\n}\n\nexport function waitForElementorEditor(): Promise< void > {\n\treturn new Promise( ( resolve ) => {\n\t\tif ( isElementorEditorReady() ) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\n\t\tconst checkReady = () => {\n\t\t\tif ( isElementorEditorReady() ) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\tsetTimeout( checkReady, 100 );\n\t\t\t}\n\t\t};\n\n\t\twindow.addEventListener(\n\t\t\t'DOMContentLoaded',\n\t\t\t() => {\n\t\t\t\tcheckReady();\n\t\t\t},\n\t\t\t{\n\t\t\t\tonce: true,\n\t\t\t}\n\t\t);\n\t} );\n}\n\nexport function waitForElementor(\n\toptions: WaitForElementorOptions = DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS\n): Promise< void > {\n\tconst { maxRetries, retryInterval, checkFn } = options;\n\n\treturn new Promise( ( resolve, reject ) => {\n\t\tlet attempts = 0;\n\n\t\tconst check = () => {\n\t\t\tif ( checkFn() ) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tattempts++;\n\n\t\t\tif ( attempts >= maxRetries ) {\n\t\t\t\treject( new Error( `Elementor not loaded after ${ maxRetries } attempts` ) );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetTimeout( check, retryInterval );\n\t\t};\n\n\t\tcheck();\n\t} );\n}\n\nexport async function whenElementorReady< T >(\n\tfn: () => T | Promise< T >,\n\toptions: WaitForElementorOptions = DEFAULT_WAIT_FOR_ELEMENTOR_OPTIONS\n): Promise< T > {\n\tawait waitForElementor( options );\n\tawait waitForElementorEditor();\n\treturn await fn();\n}\n","import { ensureElementorFrontend, isGutenbergEditor } from './editor-detection';\nimport { get$e, getElementor, getElementorFrontend, getWp } from './utils';\n\ninterface GutenbergBlockEditorDispatch {\n\tupdateBlockAttributes: ( clientId: string, attributes: Record< string, unknown > ) => void;\n}\n\ninterface GutenbergBlockEditorSelect {\n\tgetBlock: ( clientId: string ) => { name: string } | null;\n}\n\ninterface GutenbergBlock {\n\tname: string;\n}\n\nexport function injectElementCSS( elementId: string, css: string ): void {\n\tconst style = document.createElement( 'style' );\n\tstyle.id = elementId;\n\tstyle.appendChild( document.createTextNode( css ) );\n\n\tensureElementorFrontend();\n\tconst frontend = getElementorFrontend() as { elements: { $body: HTMLElement[] } } | undefined;\n\tif ( frontend ) {\n\t\tfrontend.elements.$body[ 0 ].appendChild( style );\n\t}\n}\n\nexport function removeElementCSS( elementId: string ): void {\n\tensureElementorFrontend();\n\tconst frontend = getElementorFrontend() as { elements: { $body: HTMLElement[] } } | undefined;\n\tif ( ! frontend ) {\n\t\treturn;\n\t}\n\n\tconst bodyElement = frontend.elements.$body[ 0 ];\n\tconst styleTags = bodyElement.querySelectorAll( `#${ CSS.escape( elementId ) }` );\n\n\tif ( styleTags?.length > 0 ) {\n\t\tstyleTags.forEach( ( tag: Element ) => {\n\t\t\tbodyElement.removeChild( tag );\n\t\t} );\n\t}\n}\n\nexport async function updateElementSettings( {\n\tid,\n\tsettings,\n}: {\n\tid: string;\n\tsettings: Record< string, unknown >;\n} ): Promise< unknown > {\n\tconst containerToUpdateSettings = getElementor()?.getContainer( id );\n\tif ( ! containerToUpdateSettings ) {\n\t\tthrow new Error( `Element with ID \"${ id }\" not found.` );\n\t}\n\n\tconst updateResult = await get$e()?.run( 'document/elements/settings', {\n\t\tcontainer: containerToUpdateSettings,\n\t\tsettings,\n\t\toptions: {\n\t\t\texternal: true,\n\t\t\trender: true,\n\t\t},\n\t} );\n\n\tconst frontend = getElementorFrontend() as { elements: { $body: { resize: () => void } } } | undefined;\n\tfrontend?.elements.$body.resize();\n\n\treturn updateResult;\n}\n\nexport function getElementSettings( id: string ): unknown {\n\tconst container = getElementor()?.getContainer( id );\n\tif ( ! container ) {\n\t\tthrow new Error( `Element with ID \"${ id }\" not found.` );\n\t}\n\treturn container.settings;\n}\n\nexport function getGutenbergBlockEditorApis(): {\n\tblockEditorDispatch: GutenbergBlockEditorDispatch;\n\tblockEditorSelect: GutenbergBlockEditorSelect;\n} {\n\tconst wp = getWp();\n\tif ( ! isGutenbergEditor() || ! wp ) {\n\t\tthrow new Error( 'WordPress editor API is not available' );\n\t}\n\n\tconst blockEditorDispatch = wp.data.dispatch( 'core/block-editor' ) as unknown as GutenbergBlockEditorDispatch;\n\tconst blockEditorSelect = wp.data.select( 'core/block-editor' ) as unknown as GutenbergBlockEditorSelect;\n\n\tif ( ! blockEditorDispatch || ! blockEditorSelect ) {\n\t\tthrow new Error( 'Block editor API is not available' );\n\t}\n\n\treturn { blockEditorDispatch, blockEditorSelect };\n}\n\nexport function validateAndGetGutenbergBlock(\n\tblockEditorSelect: GutenbergBlockEditorSelect,\n\tblockId: string\n): GutenbergBlock {\n\tconst block = blockEditorSelect.getBlock( blockId );\n\tif ( ! block ) {\n\t\tthrow new Error( `Block with ID \"${ blockId }\" not found` );\n\t}\n\treturn block;\n}\n\nexport function updateGutenbergBlockAttributes(\n\tblockId: string,\n\tattributes: Record< string, unknown >\n): { blockId: string; blockName: string; updatedAttributes: string[] } {\n\tconst { blockEditorDispatch, blockEditorSelect } = getGutenbergBlockEditorApis();\n\tconst block = validateAndGetGutenbergBlock( blockEditorSelect, blockId );\n\n\tblockEditorDispatch.updateBlockAttributes( blockId, attributes );\n\n\treturn {\n\t\tblockId,\n\t\tblockName: block.name,\n\t\tupdatedAttributes: Object.keys( attributes ),\n\t};\n}\n\nexport function extractElementImageData(\n\ttargetElementId: string,\n\tfallbackImageId = '',\n\tfallbackImageUrl = ''\n): { imageId: string; imageUrl: string } {\n\tlet extractedImageId = fallbackImageId;\n\tlet extractedImageUrl = fallbackImageUrl;\n\n\tif ( targetElementId && ( ! extractedImageId || ! extractedImageUrl ) ) {\n\t\tconst targetContainer = getElementor()?.getContainer?.( targetElementId );\n\t\tif ( targetContainer ) {\n\t\t\tconst imageData = targetContainer.settings.get( 'image' );\n\t\t\tif ( imageData && typeof imageData === 'object' ) {\n\t\t\t\tconst imageObj = imageData as { id?: string | number; url?: string };\n\t\t\t\textractedImageId = extractedImageId || imageObj.id?.toString() || '';\n\t\t\t\textractedImageUrl = extractedImageUrl || imageObj.url || '';\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\timageId: extractedImageId,\n\t\timageUrl: extractedImageUrl,\n\t};\n}\n\nexport function isSelectAllCheckbox( input: HTMLInputElement ): boolean {\n\tif ( ( input.id && input.id.includes( 'select-all' ) ) || ( input.name && input.name.includes( 'select-all' ) ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","import type { WpApiSettings } from './types';\nimport { getAjaxUrl, getJQuery, getWpApiSettings } from './utils';\n\ntype HeartbeatTickData = {\n\tangie_nonce?: string;\n};\n\nlet isNonceRefreshInitialized = false;\nlet nonceRefreshPromise: Promise< string > | null = null;\n\nexport function initNonceRefresh(): void {\n\tconst jQuery = getJQuery();\n\tconst wpApiSettings = getWpApiSettings();\n\tif ( isNonceRefreshInitialized || typeof jQuery === 'undefined' || ! wpApiSettings ) {\n\t\treturn;\n\t}\n\n\tisNonceRefreshInitialized = true;\n\n\tjQuery?.( document ).on( 'heartbeat-tick.angieNonceRefresh', ( _event: unknown, data: unknown ) => {\n\t\ttry {\n\t\t\tconst tickData = data as HeartbeatTickData;\n\t\t\tconst currentSettings = getWpApiSettings() as WpApiSettings | undefined;\n\t\t\tif ( tickData.angie_nonce && currentSettings && currentSettings.nonce !== tickData.angie_nonce ) {\n\t\t\t\tcurrentSettings.nonce = tickData.angie_nonce;\n\t\t\t}\n\t\t} catch ( error ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error( 'Failed to refresh nonce:', error );\n\t\t}\n\t} );\n}\n\nexport async function refreshNonce(): Promise< string > {\n\tif ( nonceRefreshPromise ) {\n\t\treturn nonceRefreshPromise;\n\t}\n\n\tnonceRefreshPromise = fetchFreshNonce();\n\n\ttry {\n\t\treturn await nonceRefreshPromise;\n\t} finally {\n\t\tnonceRefreshPromise = null;\n\t}\n}\n\nasync function fetchFreshNonce(): Promise< string > {\n\tconst ajaxUrl = new URL( getAjaxUrl() || '/wp-admin/admin-ajax.php', window.location.origin );\n\tajaxUrl.searchParams.set( 'action', 'rest-nonce' );\n\tconst response = await fetch( ajaxUrl.toString(), {\n\t\tcredentials: 'same-origin',\n\t} );\n\n\tif ( ! response.ok ) {\n\t\tthrow new Error( `Failed to refresh nonce: HTTP ${ response.status }` );\n\t}\n\n\tconst nonce = await response.text();\n\n\tif ( ! nonce || nonce === '0' ) {\n\t\tthrow new Error( 'Session expired — received invalid nonce' );\n\t}\n\n\tconst wpApiSettings = getWpApiSettings() as WpApiSettings | undefined;\n\tif ( ! wpApiSettings ) {\n\t\tthrow new Error( 'wpApiSettings not available — cannot refresh nonce' );\n\t}\n\n\twpApiSettings.nonce = nonce;\n\treturn nonce;\n}\n\nexport function isNonceError( status: number, responseText: string ): boolean {\n\treturn status === 403 && responseText.includes( 'rest_cookie_invalid_nonce' );\n}\n","import { isNonceError, refreshNonce } from './nonce-refresh';\nimport { getWpApiSettings } from './utils';\n\ntype WpApiResponse = unknown;\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS';\n\ntype CallWpApiOptions = {\n\tbinaryData?: ArrayBufferLike;\n\tcustomHeaders?: Record< string, string >;\n};\n\ntype CallWpApiResult< T > = {\n\tdata: T;\n\ttotalItems?: number;\n\ttotalPages?: number;\n};\n\nexport async function callWpApi< T = WpApiResponse >(\n\tendpoint: string,\n\tmethod: HttpMethod,\n\tdata?: Record< string, unknown >,\n\toptions?: CallWpApiOptions\n): Promise< CallWpApiResult< T > > {\n\treturn executeWpApiCall< T >( endpoint, method, data, options, true );\n}\n\nasync function executeWpApiCall< T = WpApiResponse >(\n\tendpoint: string,\n\tmethod: HttpMethod,\n\tdata?: Record< string, unknown >,\n\toptions?: CallWpApiOptions,\n\tallowNonceRetry = false\n): Promise< CallWpApiResult< T > > {\n\tconst wpApiSettings = getWpApiSettings();\n\tif ( ! wpApiSettings?.nonce || ! wpApiSettings.root ) {\n\t\tthrow new Error( 'wpApiSettings not available' );\n\t}\n\n\tconst baseUrl = wpApiSettings.root;\n\tconst urlObject = new URL( baseUrl );\n\tconst endpointUrl = new URL( endpoint, baseUrl );\n\n\turlObject.searchParams.set( 'rest_route', endpointUrl.pathname );\n\n\tfor ( const [ key, value ] of endpointUrl.searchParams.entries() ) {\n\t\turlObject.searchParams.append( key, value );\n\t}\n\n\tconst url = urlObject.toString();\n\n\tconst headers: Record< string, string > = {\n\t\t'X-WP-Nonce': wpApiSettings.nonce,\n\t\t...( options?.customHeaders || {} ),\n\t};\n\n\tif ( ! options?.binaryData && ! options?.customHeaders?.[ 'Content-Type' ] ) {\n\t\theaders[ 'Content-Type' ] = 'application/json';\n\t}\n\n\tconst requestOptions: RequestInit = {\n\t\tmethod,\n\t\theaders,\n\t\tcredentials: 'same-origin',\n\t};\n\n\tif ( options?.binaryData ) {\n\t\trequestOptions.body = options.binaryData as ArrayBuffer;\n\t} else if ( data && ( method === 'POST' || method === 'PUT' || method === 'PATCH' ) ) {\n\t\trequestOptions.body = JSON.stringify( data );\n\t}\n\n\tconst response = await fetch( url, requestOptions );\n\n\tif ( ! response.ok ) {\n\t\tconst responseText = await response.text();\n\n\t\tif ( allowNonceRetry && isNonceError( response.status, responseText ) ) {\n\t\t\tawait refreshNonce();\n\t\t\treturn executeWpApiCall< T >( endpoint, method, data, options, false );\n\t\t}\n\n\t\tthrow new Error( `HTTP error ${ response.status }: ${ responseText }` );\n\t}\n\n\tconst responseText = await response.text();\n\tconst json = extractJSONFromResponse( responseText );\n\n\tif ( json === null ) {\n\t\tthrow new Error( `Invalid response: no JSON found in: ${ responseText.substring( 0, 200 ) }` );\n\t}\n\n\tconst jsonObj = json as { success?: boolean };\n\tif ( jsonObj?.success !== undefined && ! jsonObj.success ) {\n\t\tthrow new Error( `API errors: ${ JSON.stringify( json ) }` );\n\t}\n\n\tconst totalItemsHeader = response.headers.get( 'X-WP-Total' );\n\tconst totalPagesHeader = response.headers.get( 'X-WP-TotalPages' );\n\tconst totalItems: number | undefined = totalItemsHeader ? parseInt( totalItemsHeader, 10 ) : undefined;\n\tconst totalPages: number | undefined = totalPagesHeader ? parseInt( totalPagesHeader, 10 ) : undefined;\n\n\treturn {\n\t\tdata: json as T,\n\t\ttotalItems,\n\t\ttotalPages,\n\t};\n}\n\nexport function extractJSONFromResponse( responseText: string ): unknown {\n\tconst objectStart = responseText.indexOf( '{' );\n\tconst arrayStart = responseText.indexOf( '[' );\n\n\tlet startIndex = -1;\n\tlet isArray = false;\n\n\tif ( objectStart === -1 && arrayStart === -1 ) {\n\t\treturn null;\n\t}\n\n\tif ( objectStart === -1 ) {\n\t\tstartIndex = arrayStart;\n\t\tisArray = true;\n\t} else if ( arrayStart === -1 ) {\n\t\tstartIndex = objectStart;\n\t\tisArray = false;\n\t} else if ( arrayStart < objectStart ) {\n\t\tstartIndex = arrayStart;\n\t\tisArray = true;\n\t} else {\n\t\tstartIndex = objectStart;\n\t\tisArray = false;\n\t}\n\n\tlet delimiterCount = 0;\n\tlet endIndex = -1;\n\tconst openChar = isArray ? '[' : '{';\n\tconst closeChar = isArray ? ']' : '}';\n\n\tfor ( let i = startIndex; i < responseText.length; i++ ) {\n\t\tif ( responseText[ i ] === openChar ) {\n\t\t\tdelimiterCount++;\n\t\t} else if ( responseText[ i ] === closeChar ) {\n\t\t\tdelimiterCount--;\n\t\t\tif ( delimiterCount === 0 ) {\n\t\t\t\tendIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( endIndex === -1 ) {\n\t\treturn null;\n\t}\n\n\tconst jsonString = responseText.substring( startIndex, endIndex + 1 );\n\n\ttry {\n\t\treturn JSON.parse( jsonString );\n\t} catch {\n\t\treturn null;\n\t}\n}\n","export function requireConfirmationMessage( confirmationMessage: string | undefined, context: string ): void {\n\tif ( ! confirmationMessage || confirmationMessage.trim() === '' ) {\n\t\tthrow new Error(\n\t\t\t`LLM Instructions: ${ context } changes require user confirmation. You MUST provide a confirmationMessage parameter explaining what will be changed and its impact.`\n\t\t);\n\t}\n}\n"],"mappings":"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","names":["responseText"]}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -23,8 +23,8 @@ export {
|
|
|
23
23
|
} from './elements';
|
|
24
24
|
|
|
25
25
|
export { callWpApi, extractJSONFromResponse } from './rest-client';
|
|
26
|
-
|
|
27
26
|
export { initNonceRefresh, refreshNonce, isNonceError } from './nonce-refresh';
|
|
27
|
+
export { requireConfirmationMessage } from './validation-utils';
|
|
28
28
|
|
|
29
29
|
export type {
|
|
30
30
|
ElementorChannels,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function requireConfirmationMessage( confirmationMessage: string | undefined, context: string ): void {
|
|
2
|
+
if ( ! confirmationMessage || confirmationMessage.trim() === '' ) {
|
|
3
|
+
throw new Error(
|
|
4
|
+
`LLM Instructions: ${ context } changes require user confirmation. You MUST provide a confirmationMessage parameter explaining what will be changed and its impact.`
|
|
5
|
+
);
|
|
6
|
+
}
|
|
7
|
+
}
|