@marvalt/wadapter 2.3.5 → 2.3.7

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,32 +268,35 @@ function transformWordPressMediaItems(media) {
267
268
  class GravityFormsClient {
268
269
  constructor(config) {
269
270
  this.config = config;
271
+ // Determine mode: direct for generators (Node.js), proxy for browser
272
+ this.useDirectMode = config.authMode === 'direct' && !!(config.username && config.password);
273
+ // Convention-based: Always use /api/gravity-forms-submit unless explicitly overridden
274
+ this.proxyEndpoint = config.proxyEndpoint || '/api/gravity-forms-submit';
270
275
  }
271
276
  async makeRequest(endpoint, options = {}) {
272
- // Construct URL based on auth mode
273
277
  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
- }
284
278
  const headers = {
285
279
  'Content-Type': 'application/json',
286
280
  ...options.headers,
287
281
  };
288
- // Add authentication based on mode
289
- if (this.config.authMode === 'cloudflare_proxy') ;
290
- else {
291
- // Direct mode - use basic auth
282
+ if (this.useDirectMode) {
283
+ // Direct mode: Call WordPress API directly (for generators/Node.js)
284
+ url = `${this.config.apiUrl}${endpoint}`;
285
+ // Add Basic Auth
292
286
  if (this.config.username && this.config.password) {
293
287
  const credentials = btoa(`${this.config.username}:${this.config.password}`);
294
- headers.Authorization = `Basic ${credentials}`;
288
+ headers['Authorization'] = `Basic ${credentials}`;
295
289
  }
290
+ // Add CF Access headers if provided
291
+ if (this.config.cfAccessClientId && this.config.cfAccessClientSecret) {
292
+ headers['CF-Access-Client-Id'] = this.config.cfAccessClientId;
293
+ headers['CF-Access-Client-Secret'] = this.config.cfAccessClientSecret;
294
+ }
295
+ }
296
+ else {
297
+ // Proxy mode: Use Pages Function (for browser)
298
+ const proxyEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
299
+ url = `${this.proxyEndpoint}?endpoint=${encodeURIComponent(proxyEndpoint)}`;
296
300
  }
297
301
  const response = await fetch(url, {
298
302
  ...options,
@@ -317,56 +321,37 @@ class GravityFormsClient {
317
321
  throw new Error(`Failed to parse JSON response: ${error.message}`);
318
322
  }
319
323
  }
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
324
  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}`);
325
+ // Always use custom gf-api/v1 endpoint (from custom plugin)
326
+ const endpoint = `/forms/${id}`;
337
327
  return this.makeRequest(endpoint);
338
328
  }
339
329
  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');
330
+ // Always use custom gf-api/v1 endpoint (from custom plugin)
331
+ const endpoint = '/forms';
346
332
  return this.makeRequest(endpoint);
347
333
  }
348
334
  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
335
+ // Always use custom gf-api/v1 endpoint (from custom plugin)
336
+ const endpoint = `/forms/${id}/config`;
355
337
  return this.makeRequest(endpoint);
356
338
  }
357
339
  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
340
+ // Always use custom gf-api/v1 submit endpoint (from custom plugin)
341
+ const endpoint = `/forms/${formId}/submit`;
342
+ // Merge custom headers (e.g., Turnstile token) with default headers
343
+ const headers = {
344
+ 'Content-Type': 'application/json',
345
+ ...(submission.headers || {}),
346
+ };
361
347
  return this.makeRequest(endpoint, {
362
348
  method: 'POST',
363
- body: JSON.stringify(submission),
349
+ headers,
350
+ body: JSON.stringify(submission.field_values),
364
351
  });
365
352
  }
366
353
  async getHealth() {
367
- const endpoint = this.config.authMode === 'cloudflare_proxy'
368
- ? '/gf-api/v1/health'
369
- : '/wp-json/gf/v2/health';
354
+ const endpoint = '/health';
370
355
  return this.makeRequest(endpoint);
371
356
  }
372
357
  }
@@ -1934,15 +1919,115 @@ const WordPressContent = ({ content, className = '', showExcerpt = false, showDa
1934
1919
  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
1920
  };
1936
1921
 
1922
+ const TurnstileWidget = ({ siteKey, action, cData, onSuccess, onError, onExpire, theme = 'auto', size = 'normal', tabIndex, }) => {
1923
+ const widgetRef = require$$0.useRef(null);
1924
+ const widgetId = require$$0.useRef(null);
1925
+ const scriptLoaded = require$$0.useRef(false);
1926
+ require$$0.useEffect(() => {
1927
+ if (!widgetRef.current || !siteKey)
1928
+ return;
1929
+ const loadTurnstile = () => {
1930
+ if (window.turnstile && widgetRef.current && !widgetId.current) {
1931
+ try {
1932
+ widgetId.current = window.turnstile.render(widgetRef.current, {
1933
+ sitekey: siteKey,
1934
+ callback: onSuccess,
1935
+ 'error-callback': onError,
1936
+ 'expired-callback': onExpire,
1937
+ theme,
1938
+ size,
1939
+ tabindex: tabIndex,
1940
+ });
1941
+ }
1942
+ catch (error) {
1943
+ console.error('Failed to render Turnstile widget:', error);
1944
+ onError?.();
1945
+ }
1946
+ }
1947
+ };
1948
+ // Check if Turnstile is already loaded
1949
+ if (window.turnstile) {
1950
+ loadTurnstile();
1951
+ }
1952
+ else if (!scriptLoaded.current) {
1953
+ // Load Turnstile script
1954
+ scriptLoaded.current = true;
1955
+ const script = document.createElement('script');
1956
+ script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
1957
+ script.async = true;
1958
+ script.defer = true;
1959
+ script.onload = loadTurnstile;
1960
+ script.onerror = () => {
1961
+ console.error('Failed to load Turnstile script');
1962
+ onError?.();
1963
+ };
1964
+ document.head.appendChild(script);
1965
+ }
1966
+ return () => {
1967
+ if (widgetId.current && window.turnstile) {
1968
+ try {
1969
+ window.turnstile.remove(widgetId.current);
1970
+ }
1971
+ catch (error) {
1972
+ console.error('Failed to remove Turnstile widget:', error);
1973
+ }
1974
+ widgetId.current = null;
1975
+ }
1976
+ };
1977
+ }, [siteKey, onSuccess, onError, onExpire, theme, size, tabIndex]);
1978
+ return jsxRuntimeExports.jsx("div", { ref: widgetRef, className: "cf-turnstile" });
1979
+ };
1980
+
1937
1981
  const GravityForm = ({ formId, config, className = '', onSubmit, onError, }) => {
1938
1982
  const { form, loading, error, submitting, result, submitForm } = useGravityForms(formId, config);
1939
1983
  const [formData, setFormData] = require$$0.useState({});
1984
+ const [turnstileToken, setTurnstileToken] = require$$0.useState(null);
1985
+ const [turnstileError, setTurnstileError] = require$$0.useState(null);
1986
+ // Get Turnstile site key from environment - memoized to prevent re-renders
1987
+ const turnstilesiteKey = require$$0.useMemo(() => {
1988
+ try {
1989
+ // @ts-ignore - import.meta is a Vite-specific global
1990
+ 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) {
1991
+ // @ts-ignore
1992
+ const key = undefined.VITE_TURNSTILE_SITE_KEY;
1993
+ // Ensure we return a string or undefined, not an object
1994
+ return typeof key === 'string' ? key : undefined;
1995
+ }
1996
+ }
1997
+ catch (e) {
1998
+ // import.meta not available
1999
+ }
2000
+ return undefined;
2001
+ }, []); // Empty deps - site key doesn't change during runtime
2002
+ // Memoize Turnstile callbacks to prevent widget re-renders
2003
+ const handleTurnstileSuccess = require$$0.useCallback((token) => {
2004
+ setTurnstileToken(token);
2005
+ setTurnstileError(null);
2006
+ }, []);
2007
+ const handleTurnstileError = require$$0.useCallback(() => {
2008
+ setTurnstileToken(null);
2009
+ setTurnstileError('Verification failed. Please try again.');
2010
+ }, []);
2011
+ const handleTurnstileExpire = require$$0.useCallback(() => {
2012
+ setTurnstileToken(null);
2013
+ setTurnstileError('Verification expired. Please verify again.');
2014
+ }, []);
1940
2015
  const handleSubmit = async (e) => {
1941
2016
  e.preventDefault();
2017
+ // Check Turnstile token if enabled
2018
+ if (turnstilesiteKey && !turnstileToken) {
2019
+ setTurnstileError('Please complete the verification');
2020
+ return;
2021
+ }
1942
2022
  try {
1943
2023
  const submission = {
1944
2024
  form_id: formId,
1945
2025
  field_values: formData,
2026
+ ...(turnstileToken ? {
2027
+ headers: {
2028
+ 'cf-turnstile-response': turnstileToken
2029
+ }
2030
+ } : {})
1946
2031
  };
1947
2032
  await submitForm(submission);
1948
2033
  if (onSubmit && result) {
@@ -1970,7 +2055,11 @@ const GravityForm = ({ formId, config, className = '', onSubmit, onError, }) =>
1970
2055
  if (!form) {
1971
2056
  return jsxRuntimeExports.jsx("div", { className: `gravity-form not-found ${className}`, children: "Form not found" });
1972
2057
  }
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 }))] }) }));
2058
+ 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
2059
+ ? 'Submitting...'
2060
+ : (turnstilesiteKey && !turnstileToken)
2061
+ ? 'Complete verification first'
2062
+ : 'Submit' }), result && (jsxRuntimeExports.jsx("div", { className: `result ${result.success ? 'success' : 'error'}`, children: result.message }))] }) }));
1974
2063
  };
1975
2064
 
1976
2065
  const WordPressContext = require$$0.createContext(undefined);
@@ -2093,7 +2182,7 @@ function getFormById(id) {
2093
2182
  return (gravityFormsStaticData?.forms ?? []).find(f => String(f.id) === key);
2094
2183
  }
2095
2184
 
2096
- let document;
2185
+ let document$1;
2097
2186
  let offset;
2098
2187
  let output;
2099
2188
  let stack;
@@ -2120,7 +2209,7 @@ function Frame(block, tokenStart, tokenLength, prevOffset, leadingHtmlStart) {
2120
2209
  };
2121
2210
  }
2122
2211
  const parse = (doc) => {
2123
- document = doc;
2212
+ document$1 = doc;
2124
2213
  offset = 0;
2125
2214
  output = [];
2126
2215
  stack = [];
@@ -2153,7 +2242,7 @@ function proceed() {
2153
2242
  if (null !== leadingHtmlStart) {
2154
2243
  output.push(
2155
2244
  Freeform(
2156
- document.substr(
2245
+ document$1.substr(
2157
2246
  leadingHtmlStart,
2158
2247
  startOffset - leadingHtmlStart
2159
2248
  )
@@ -2194,7 +2283,7 @@ function proceed() {
2194
2283
  return true;
2195
2284
  }
2196
2285
  const stackTop = stack.pop();
2197
- const html = document.substr(
2286
+ const html = document$1.substr(
2198
2287
  stackTop.prevOffset,
2199
2288
  startOffset - stackTop.prevOffset
2200
2289
  );
@@ -2222,7 +2311,7 @@ function parseJSON(input) {
2222
2311
  }
2223
2312
  }
2224
2313
  function nextToken() {
2225
- const matches = tokenizer.exec(document);
2314
+ const matches = tokenizer.exec(document$1);
2226
2315
  if (null === matches) {
2227
2316
  return ["no-more-tokens", "", null, 0, 0];
2228
2317
  }
@@ -2252,16 +2341,16 @@ function nextToken() {
2252
2341
  return ["block-opener", name, attrs, startedAt, length];
2253
2342
  }
2254
2343
  function addFreeform(rawLength) {
2255
- const length = document.length - offset;
2344
+ const length = document$1.length - offset;
2256
2345
  if (0 === length) {
2257
2346
  return;
2258
2347
  }
2259
- output.push(Freeform(document.substr(offset, length)));
2348
+ output.push(Freeform(document$1.substr(offset, length)));
2260
2349
  }
2261
2350
  function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
2262
2351
  const parent = stack[stack.length - 1];
2263
2352
  parent.block.innerBlocks.push(block);
2264
- const html = document.substr(
2353
+ const html = document$1.substr(
2265
2354
  parent.prevOffset,
2266
2355
  tokenStart - parent.prevOffset
2267
2356
  );
@@ -2274,7 +2363,7 @@ function addInnerBlock(block, tokenStart, tokenLength, lastOffset) {
2274
2363
  }
2275
2364
  function addBlockFromStack(endOffset) {
2276
2365
  const { block, leadingHtmlStart, prevOffset, tokenStart } = stack.pop();
2277
- const html = endOffset ? document.substr(prevOffset, endOffset - prevOffset) : document.substr(prevOffset);
2366
+ const html = endOffset ? document$1.substr(prevOffset, endOffset - prevOffset) : document$1.substr(prevOffset);
2278
2367
  if (html) {
2279
2368
  block.innerHTML += html;
2280
2369
  block.innerContent.push(html);
@@ -2282,7 +2371,7 @@ function addBlockFromStack(endOffset) {
2282
2371
  if (null !== leadingHtmlStart) {
2283
2372
  output.push(
2284
2373
  Freeform(
2285
- document.substr(
2374
+ document$1.substr(
2286
2375
  leadingHtmlStart,
2287
2376
  tokenStart - leadingHtmlStart
2288
2377
  )