@marvalt/wadapter 2.3.5 → 2.3.6

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.js CHANGED
@@ -4,6 +4,7 @@ var require$$0 = require('react');
4
4
  var fs = require('fs');
5
5
  var path = require('path');
6
6
 
7
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
7
8
  /**
8
9
  * @license GPL-3.0-or-later
9
10
  *
@@ -267,33 +268,18 @@ function transformWordPressMediaItems(media) {
267
268
  class GravityFormsClient {
268
269
  constructor(config) {
269
270
  this.config = config;
271
+ // Convention-based: Always use /api/gravity-forms-submit unless explicitly overridden
272
+ // This matches the Mautic pattern for consistency
273
+ this.proxyEndpoint = config.proxyEndpoint || '/api/gravity-forms-submit';
270
274
  }
271
275
  async makeRequest(endpoint, options = {}) {
272
- // Construct URL based on auth mode
273
- let url;
274
- if (this.config.authMode === 'cloudflare_proxy') {
275
- // For proxy modes, pass the full REST path including /wp-json as query parameter
276
- const baseUrl = this.getBaseUrl();
277
- const fullEndpoint = `/wp-json${endpoint}`;
278
- url = `${baseUrl}?endpoint=${encodeURIComponent(fullEndpoint)}`;
279
- }
280
- else {
281
- // For direct mode, construct the full API URL
282
- url = `${this.config.apiUrl}${endpoint}`;
283
- }
276
+ // Always use proxy endpoint (convention-based, like Mautic)
277
+ const proxyEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
278
+ const url = `${this.proxyEndpoint}?endpoint=${encodeURIComponent(proxyEndpoint)}`;
284
279
  const headers = {
285
280
  'Content-Type': 'application/json',
286
281
  ...options.headers,
287
282
  };
288
- // Add authentication based on mode
289
- if (this.config.authMode === 'cloudflare_proxy') ;
290
- else {
291
- // Direct mode - use basic auth
292
- if (this.config.username && this.config.password) {
293
- const credentials = btoa(`${this.config.username}:${this.config.password}`);
294
- headers.Authorization = `Basic ${credentials}`;
295
- }
296
- }
297
283
  const response = await fetch(url, {
298
284
  ...options,
299
285
  headers,
@@ -317,56 +303,37 @@ class GravityFormsClient {
317
303
  throw new Error(`Failed to parse JSON response: ${error.message}`);
318
304
  }
319
305
  }
320
- getBaseUrl() {
321
- switch (this.config.authMode) {
322
- case 'cloudflare_proxy':
323
- return this.config.cloudflareWorkerUrl || '';
324
- default:
325
- return this.config.apiUrl || '';
326
- }
327
- }
328
306
  async getForm(id) {
329
- // If using custom endpoint (gf-api plugin), use it for both modes
330
- // Otherwise: proxy uses gf-api/v1, direct uses official gf/v2
331
- const useCustom = this.config.useCustomEndpoint;
332
- const endpoint = useCustom
333
- ? `/forms/${id}` // apiUrl already includes /wp-json/gf-api/v1
334
- : (this.config.authMode === 'cloudflare_proxy'
335
- ? `/gf-api/v1/forms/${id}`
336
- : `/wp-json/gf/v2/forms/${id}`);
307
+ // Always use custom gf-api/v1 endpoint (from custom plugin)
308
+ const endpoint = `/forms/${id}`;
337
309
  return this.makeRequest(endpoint);
338
310
  }
339
311
  async getForms() {
340
- const useCustom = this.config.useCustomEndpoint;
341
- const endpoint = useCustom
342
- ? '/forms' // apiUrl already includes /wp-json/gf-api/v1
343
- : (this.config.authMode === 'cloudflare_proxy'
344
- ? '/gf-api/v1/forms'
345
- : '/wp-json/gf/v2/forms');
312
+ // Always use custom gf-api/v1 endpoint (from custom plugin)
313
+ const endpoint = '/forms';
346
314
  return this.makeRequest(endpoint);
347
315
  }
348
316
  async getFormConfig(id) {
349
- const useCustom = this.config.useCustomEndpoint;
350
- const endpoint = useCustom
351
- ? `/forms/${id}/config` // apiUrl already includes /wp-json/gf-api/v1
352
- : (this.config.authMode === 'cloudflare_proxy'
353
- ? `/gf-api/v1/forms/${id}/config`
354
- : `/wp-json/gf/v2/forms/${id}`); // v2 returns full form including settings
317
+ // Always use custom gf-api/v1 endpoint (from custom plugin)
318
+ const endpoint = `/forms/${id}/config`;
355
319
  return this.makeRequest(endpoint);
356
320
  }
357
321
  async submitForm(formId, submission) {
358
- const endpoint = this.config.authMode === 'cloudflare_proxy'
359
- ? `/gf-api/v1/forms/${formId}/submit`
360
- : `/wp-json/gf/v2/forms/${formId}/submissions`; // official GF REST v2 submissions
322
+ // Always use custom gf-api/v1 submit endpoint (from custom plugin)
323
+ const endpoint = `/forms/${formId}/submit`;
324
+ // Merge custom headers (e.g., Turnstile token) with default headers
325
+ const headers = {
326
+ 'Content-Type': 'application/json',
327
+ ...(submission.headers || {}),
328
+ };
361
329
  return this.makeRequest(endpoint, {
362
330
  method: 'POST',
363
- body: JSON.stringify(submission),
331
+ headers,
332
+ body: JSON.stringify(submission.field_values),
364
333
  });
365
334
  }
366
335
  async getHealth() {
367
- const endpoint = this.config.authMode === 'cloudflare_proxy'
368
- ? '/gf-api/v1/health'
369
- : '/wp-json/gf/v2/health';
336
+ const endpoint = '/health';
370
337
  return this.makeRequest(endpoint);
371
338
  }
372
339
  }
@@ -1934,15 +1901,115 @@ const WordPressContent = ({ content, className = '', showExcerpt = false, showDa
1934
1901
  return (jsxRuntimeExports.jsxs("article", { className: `wordpress-content ${className}`, children: [jsxRuntimeExports.jsxs("header", { className: "content-header", children: [jsxRuntimeExports.jsx("h1", { className: "content-title", dangerouslySetInnerHTML: { __html: content.title.rendered } }), showDate && (jsxRuntimeExports.jsx("time", { className: "content-date", dateTime: content.date, children: new Date(content.date).toLocaleDateString() })), showAuthor && 'author' in content && (jsxRuntimeExports.jsxs("span", { className: "content-author", children: ["Author ID: ", content.author] }))] }), showExcerpt && content.excerpt && (jsxRuntimeExports.jsx("div", { className: "content-excerpt", dangerouslySetInnerHTML: { __html: content.excerpt.rendered } })), jsxRuntimeExports.jsx("div", { className: "content-body", dangerouslySetInnerHTML: { __html: content.content.rendered } })] }));
1935
1902
  };
1936
1903
 
1904
+ const TurnstileWidget = ({ siteKey, action, cData, onSuccess, onError, onExpire, theme = 'auto', size = 'normal', tabIndex, }) => {
1905
+ const widgetRef = require$$0.useRef(null);
1906
+ const widgetId = require$$0.useRef(null);
1907
+ const scriptLoaded = require$$0.useRef(false);
1908
+ require$$0.useEffect(() => {
1909
+ if (!widgetRef.current || !siteKey)
1910
+ return;
1911
+ const loadTurnstile = () => {
1912
+ if (window.turnstile && widgetRef.current && !widgetId.current) {
1913
+ try {
1914
+ widgetId.current = window.turnstile.render(widgetRef.current, {
1915
+ sitekey: siteKey,
1916
+ callback: onSuccess,
1917
+ 'error-callback': onError,
1918
+ 'expired-callback': onExpire,
1919
+ theme,
1920
+ size,
1921
+ tabindex: tabIndex,
1922
+ });
1923
+ }
1924
+ catch (error) {
1925
+ console.error('Failed to render Turnstile widget:', error);
1926
+ onError?.();
1927
+ }
1928
+ }
1929
+ };
1930
+ // Check if Turnstile is already loaded
1931
+ if (window.turnstile) {
1932
+ loadTurnstile();
1933
+ }
1934
+ else if (!scriptLoaded.current) {
1935
+ // Load Turnstile script
1936
+ scriptLoaded.current = true;
1937
+ const script = document.createElement('script');
1938
+ script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
1939
+ script.async = true;
1940
+ script.defer = true;
1941
+ script.onload = loadTurnstile;
1942
+ script.onerror = () => {
1943
+ console.error('Failed to load Turnstile script');
1944
+ onError?.();
1945
+ };
1946
+ document.head.appendChild(script);
1947
+ }
1948
+ return () => {
1949
+ if (widgetId.current && window.turnstile) {
1950
+ try {
1951
+ window.turnstile.remove(widgetId.current);
1952
+ }
1953
+ catch (error) {
1954
+ console.error('Failed to remove Turnstile widget:', error);
1955
+ }
1956
+ widgetId.current = null;
1957
+ }
1958
+ };
1959
+ }, [siteKey, onSuccess, onError, onExpire, theme, size, tabIndex]);
1960
+ return jsxRuntimeExports.jsx("div", { ref: widgetRef, className: "cf-turnstile" });
1961
+ };
1962
+
1937
1963
  const GravityForm = ({ formId, config, className = '', onSubmit, onError, }) => {
1938
1964
  const { form, loading, error, submitting, result, submitForm } = useGravityForms(formId, config);
1939
1965
  const [formData, setFormData] = require$$0.useState({});
1966
+ const [turnstileToken, setTurnstileToken] = require$$0.useState(null);
1967
+ const [turnstileError, setTurnstileError] = require$$0.useState(null);
1968
+ // Get Turnstile site key from environment - memoized to prevent re-renders
1969
+ const turnstilesiteKey = require$$0.useMemo(() => {
1970
+ try {
1971
+ // @ts-ignore - import.meta is a Vite-specific global
1972
+ if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== 'undefined' && undefined) {
1973
+ // @ts-ignore
1974
+ const key = undefined.VITE_TURNSTILE_SITE_KEY;
1975
+ // Ensure we return a string or undefined, not an object
1976
+ return typeof key === 'string' ? key : undefined;
1977
+ }
1978
+ }
1979
+ catch (e) {
1980
+ // import.meta not available
1981
+ }
1982
+ return undefined;
1983
+ }, []); // Empty deps - site key doesn't change during runtime
1984
+ // Memoize Turnstile callbacks to prevent widget re-renders
1985
+ const handleTurnstileSuccess = require$$0.useCallback((token) => {
1986
+ setTurnstileToken(token);
1987
+ setTurnstileError(null);
1988
+ }, []);
1989
+ const handleTurnstileError = require$$0.useCallback(() => {
1990
+ setTurnstileToken(null);
1991
+ setTurnstileError('Verification failed. Please try again.');
1992
+ }, []);
1993
+ const handleTurnstileExpire = require$$0.useCallback(() => {
1994
+ setTurnstileToken(null);
1995
+ setTurnstileError('Verification expired. Please verify again.');
1996
+ }, []);
1940
1997
  const handleSubmit = async (e) => {
1941
1998
  e.preventDefault();
1999
+ // Check Turnstile token if enabled
2000
+ if (turnstilesiteKey && !turnstileToken) {
2001
+ setTurnstileError('Please complete the verification');
2002
+ return;
2003
+ }
1942
2004
  try {
1943
2005
  const submission = {
1944
2006
  form_id: formId,
1945
2007
  field_values: formData,
2008
+ ...(turnstileToken ? {
2009
+ headers: {
2010
+ 'cf-turnstile-response': turnstileToken
2011
+ }
2012
+ } : {})
1946
2013
  };
1947
2014
  await submitForm(submission);
1948
2015
  if (onSubmit && result) {
@@ -1970,7 +2037,11 @@ const GravityForm = ({ formId, config, className = '', onSubmit, onError, }) =>
1970
2037
  if (!form) {
1971
2038
  return jsxRuntimeExports.jsx("div", { className: `gravity-form not-found ${className}`, children: "Form not found" });
1972
2039
  }
1973
- return (jsxRuntimeExports.jsx("div", { className: `gravity-form ${className}`, children: jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, children: [jsxRuntimeExports.jsx("h2", { children: form.title }), form.description && jsxRuntimeExports.jsx("p", { children: form.description }), form.fields.map(field => (jsxRuntimeExports.jsxs("div", { className: `field field-${field.type}`, children: [jsxRuntimeExports.jsxs("label", { htmlFor: `field_${field.id}`, children: [field.label, field.required && jsxRuntimeExports.jsx("span", { className: "required", children: "*" })] }), field.description && (jsxRuntimeExports.jsx("p", { className: "field-description", children: field.description })), field.type === 'text' && (jsxRuntimeExports.jsx("input", { type: "text", id: `field_${field.id}`, name: field.label, required: field.required, placeholder: field.placeholder, onChange: (e) => handleFieldChange(field.id.toString(), e.target.value) })), field.type === 'email' && (jsxRuntimeExports.jsx("input", { type: "email", id: `field_${field.id}`, name: field.label, required: field.required, placeholder: field.placeholder, onChange: (e) => handleFieldChange(field.id.toString(), e.target.value) })), field.type === 'textarea' && (jsxRuntimeExports.jsx("textarea", { id: `field_${field.id}`, name: field.label, required: field.required, placeholder: field.placeholder, onChange: (e) => handleFieldChange(field.id.toString(), e.target.value) })), field.type === 'select' && field.choices && (jsxRuntimeExports.jsxs("select", { id: `field_${field.id}`, name: field.label, required: field.required, onChange: (e) => handleFieldChange(field.id.toString(), e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: "Select an option" }), field.choices.map((choice, index) => (jsxRuntimeExports.jsx("option", { value: choice.value, children: choice.text }, index)))] }))] }, field.id))), jsxRuntimeExports.jsx("button", { type: "submit", disabled: submitting, children: submitting ? 'Submitting...' : 'Submit' }), result && (jsxRuntimeExports.jsx("div", { className: `result ${result.success ? 'success' : 'error'}`, children: result.message }))] }) }));
2040
+ return (jsxRuntimeExports.jsx("div", { className: `gravity-form ${className}`, children: jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, children: [jsxRuntimeExports.jsx("h2", { children: form.title }), form.description && jsxRuntimeExports.jsx("p", { children: form.description }), form.fields.map(field => (jsxRuntimeExports.jsxs("div", { className: `field field-${field.type}`, children: [jsxRuntimeExports.jsxs("label", { htmlFor: `field_${field.id}`, children: [field.label, field.required && jsxRuntimeExports.jsx("span", { className: "required", children: "*" })] }), field.description && (jsxRuntimeExports.jsx("p", { className: "field-description", children: field.description })), field.type === 'text' && (jsxRuntimeExports.jsx("input", { type: "text", id: `field_${field.id}`, name: field.label, required: field.required, placeholder: field.placeholder, onChange: (e) => handleFieldChange(field.id.toString(), e.target.value) })), field.type === 'email' && (jsxRuntimeExports.jsx("input", { type: "email", id: `field_${field.id}`, name: field.label, required: field.required, placeholder: field.placeholder, onChange: (e) => handleFieldChange(field.id.toString(), e.target.value) })), field.type === 'textarea' && (jsxRuntimeExports.jsx("textarea", { id: `field_${field.id}`, name: field.label, required: field.required, placeholder: field.placeholder, onChange: (e) => handleFieldChange(field.id.toString(), e.target.value) })), field.type === 'select' && field.choices && (jsxRuntimeExports.jsxs("select", { id: `field_${field.id}`, name: field.label, required: field.required, onChange: (e) => handleFieldChange(field.id.toString(), e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: "Select an option" }), field.choices.map((choice, index) => (jsxRuntimeExports.jsx("option", { value: choice.value, children: choice.text }, index)))] }))] }, field.id))), turnstilesiteKey && (jsxRuntimeExports.jsxs("div", { className: "form-turnstile", children: [jsxRuntimeExports.jsx(TurnstileWidget, { siteKey: turnstilesiteKey, onSuccess: handleTurnstileSuccess, onError: handleTurnstileError, onExpire: handleTurnstileExpire, theme: "auto", size: "normal" }), turnstileError && (jsxRuntimeExports.jsx("p", { className: "field-error turnstile-error", children: turnstileError }))] })), jsxRuntimeExports.jsx("button", { type: "submit", disabled: submitting || (!!turnstilesiteKey && !turnstileToken), children: submitting
2041
+ ? 'Submitting...'
2042
+ : (turnstilesiteKey && !turnstileToken)
2043
+ ? 'Complete verification first'
2044
+ : 'Submit' }), result && (jsxRuntimeExports.jsx("div", { className: `result ${result.success ? 'success' : 'error'}`, children: result.message }))] }) }));
1974
2045
  };
1975
2046
 
1976
2047
  const WordPressContext = require$$0.createContext(undefined);
@@ -2093,7 +2164,7 @@ function getFormById(id) {
2093
2164
  return (gravityFormsStaticData?.forms ?? []).find(f => String(f.id) === key);
2094
2165
  }
2095
2166
 
2096
- let document;
2167
+ let document$1;
2097
2168
  let offset;
2098
2169
  let output;
2099
2170
  let stack;
@@ -2120,7 +2191,7 @@ function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {
2120
2191
  };
2121
2192
  }
2122
2193
  const parse = (doc) => {
2123
- document = doc;
2194
+ document$1 = doc;
2124
2195
  offset = 0;
2125
2196
  output = [];
2126
2197
  stack = [];
@@ -2153,7 +2224,7 @@ function proceed() {
2153
2224
  if (null !== leadingHtmlStart) {
2154
2225
  output.push(
2155
2226
  Freeform(
2156
- document.substr(
2227
+ document$1.substr(
2157
2228
  leadingHtmlStart,
2158
2229
  startOffset - leadingHtmlStart
2159
2230
  )
@@ -2194,7 +2265,7 @@ function proceed() {
2194
2265
  return true;
2195
2266
  }
2196
2267
  const stackTop = stack.pop();
2197
- const html = document.substr(
2268
+ const html = document$1.substr(
2198
2269
  stackTop.prevOffset,
2199
2270
  startOffset - stackTop.prevOffset
2200
2271
  );
@@ -2222,7 +2293,7 @@ function parseJSON(input) {
2222
2293
  }
2223
2294
  }
2224
2295
  function nextToken() {
2225
- const matches = tokenizer.exec(document);
2296
+ const matches = tokenizer.exec(document$1);
2226
2297
  if (null === matches) {
2227
2298
  return ["no-more-tokens", "", null, 0, 0];
2228
2299
  }
@@ -2252,16 +2323,16 @@ function nextToken() {
2252
2323
  return ["block-opener", name, attrs, startedAt, length];
2253
2324
  }
2254
2325
  function addFreeform(rawLength) {
2255
- const length = document.length - offset;
2326
+ const length = document$1.length - offset;
2256
2327
  if (0 === length) {
2257
2328
  return;
2258
2329
  }
2259
- output.push(Freeform(document.substr(offset, length)));
2330
+ output.push(Freeform(document$1.substr(offset, length)));
2260
2331
  }
2261
2332
  function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
2262
2333
  const parent = stack[stack.length - 1];
2263
2334
  parent.block.innerBlocks.push(block);
2264
- const html = document.substr(
2335
+ const html = document$1.substr(
2265
2336
  parent.prevOffset,
2266
2337
  tokenStart - parent.prevOffset
2267
2338
  );
@@ -2274,7 +2345,7 @@ function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
2274
2345
  }
2275
2346
  function addBlockFromStack(endOffset) {
2276
2347
  const { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();
2277
- const html = endOffset ? document.substr(prevOffset, endOffset - prevOffset) : document.substr(prevOffset);
2348
+ const html = endOffset ? document$1.substr(prevOffset, endOffset - prevOffset) : document$1.substr(prevOffset);
2278
2349
  if (html) {
2279
2350
  block.innerHTML += html;
2280
2351
  block.innerContent.push(html);
@@ -2282,7 +2353,7 @@ function addBlockFromStack(endOffset) {
2282
2353
  if (null !== leadingHtmlStart) {
2283
2354
  output.push(
2284
2355
  Freeform(
2285
- document.substr(
2356
+ document$1.substr(
2286
2357
  leadingHtmlStart,
2287
2358
  tokenStart - leadingHtmlStart
2288
2359
  )