@marvalt/madapter 2.1.0 → 2.2.1

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.ts CHANGED
@@ -461,6 +461,52 @@ declare const useMauticEvent: () => {
461
461
  trackPageview: () => void;
462
462
  };
463
463
 
464
+ /**
465
+ * @license GPL-3.0-or-later
466
+ *
467
+ * This file is part of the MarVAlt Open SDK.
468
+ * Copyright (c) 2025 Vibune Pty Ltd.
469
+ *
470
+ * This program is free software: you can redistribute it and/or modify
471
+ * it under the terms of the GNU General Public License as published by
472
+ * the Free Software Foundation, either version 3 of the License, or
473
+ * (at your option) any later version.
474
+ *
475
+ * This program is distributed in the hope that it will be useful,
476
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
477
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
478
+ * See the GNU General Public License for more details.
479
+ */
480
+
481
+ declare global {
482
+ interface Window {
483
+ turnstile?: {
484
+ render: (element: HTMLElement, options: TurnstileOptions) => string;
485
+ remove: (widgetId: string) => void;
486
+ reset: (widgetId: string) => void;
487
+ };
488
+ }
489
+ }
490
+ interface TurnstileOptions {
491
+ sitekey: string;
492
+ callback?: (token: string) => void;
493
+ 'error-callback'?: () => void;
494
+ 'expired-callback'?: () => void;
495
+ theme?: 'light' | 'dark' | 'auto';
496
+ size?: 'normal' | 'compact';
497
+ tabindex?: number;
498
+ }
499
+ interface TurnstileWidgetProps {
500
+ siteKey: string;
501
+ onSuccess: (token: string) => void;
502
+ onError?: () => void;
503
+ onExpire?: () => void;
504
+ theme?: 'light' | 'dark' | 'auto';
505
+ size?: 'normal' | 'compact';
506
+ tabIndex?: number;
507
+ }
508
+ declare const TurnstileWidget: React.FC<TurnstileWidgetProps>;
509
+
464
510
  /**
465
511
  * Set the default Mautic client for hooks
466
512
  */
@@ -770,5 +816,5 @@ declare const sanitizeFormData: (formData: Record<string, any>) => Record<string
770
816
  */
771
817
  declare const formatFormDataForSubmission: (formData: Record<string, any>) => Record<string, any>;
772
818
 
773
- export { MauticClient, MauticForm, MauticGenerator, MauticProvider, MauticService, MauticTracking, createMauticConfig, formatFormDataForSubmission, generateMauticData, getAllFieldTypes, getDataMetadata, getDefaultMauticConfig, getFormByAlias, getFormById, getFormFieldByAlias, getFormsByFieldType, getFormsByType, getFormsCountByStatus, getMauticConfigSummary, getMauticData, getPublishedForms, isDataLoaded, isFormDataValid, isMauticEnabled, isRequiredFieldValid, isValidEmail, isValidPhone, isValidUrl, loadMauticData, mauticService, mergeMauticConfig, sanitizeFormData, searchForms, setMauticClient, useMauticAddTags, useMauticAddToSegment, useMauticClient, useMauticConfig, useMauticContactByEmail, useMauticContactTags, useMauticContext, useMauticCreateContact, useMauticEvent, useMauticEventTracking, useMauticForm, useMauticFormSubmission, useMauticForms, useMauticRemoveFromSegment, useMauticRemoveTags, useMauticSegments, useMauticTags, useMauticTracking, useMauticUpdateContact, validateField, validateFormData, validateMauticConfig };
819
+ export { MauticClient, MauticForm, MauticGenerator, MauticProvider, MauticService, MauticTracking, TurnstileWidget, createMauticConfig, formatFormDataForSubmission, generateMauticData, getAllFieldTypes, getDataMetadata, getDefaultMauticConfig, getFormByAlias, getFormById, getFormFieldByAlias, getFormsByFieldType, getFormsByType, getFormsCountByStatus, getMauticConfigSummary, getMauticData, getPublishedForms, isDataLoaded, isFormDataValid, isMauticEnabled, isRequiredFieldValid, isValidEmail, isValidPhone, isValidUrl, loadMauticData, mauticService, mergeMauticConfig, sanitizeFormData, searchForms, setMauticClient, useMauticAddTags, useMauticAddToSegment, useMauticClient, useMauticConfig, useMauticContactByEmail, useMauticContactTags, useMauticContext, useMauticCreateContact, useMauticEvent, useMauticEventTracking, useMauticForm, useMauticFormSubmission, useMauticForms, useMauticRemoveFromSegment, useMauticRemoveTags, useMauticSegments, useMauticTags, useMauticTracking, useMauticUpdateContact, validateField, validateFormData, validateMauticConfig };
774
820
  export type { AuthMode, MauticApiResponse, MauticConfig, MauticContact, MauticEvent, MauticFormAction, MauticFormConfig, MauticFormData, MauticFormField, MauticFormSubmission, MauticForm$1 as MauticFormType, MauticGeneratorConfig, MauticStaticData, MauticTrackingConfig };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGxE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGpF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAGtG,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,UAAU,IAAI,cAAc,EAC5B,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,gBAAgB,EAChB,cAAc,GACf,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,EACf,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGxE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGpF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACtG,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAGrE,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,UAAU,IAAI,cAAc,EAC5B,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,gBAAgB,EAChB,cAAc,GACf,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,EACf,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,oBAAoB,CAAC"}
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import React, { useState, useEffect, createContext, useMemo, useContext } from 'react';
3
+ import React, { useRef, useEffect, useState, createContext, useMemo, useContext } from 'react';
4
4
  import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
5
5
 
6
6
  /**
@@ -2343,13 +2343,93 @@ const useMauticRemoveFromSegment = () => {
2343
2343
  });
2344
2344
  };
2345
2345
 
2346
+ const TurnstileWidget = ({ siteKey, onSuccess, onError, onExpire, theme = 'auto', size = 'normal', tabIndex, }) => {
2347
+ const widgetRef = useRef(null);
2348
+ const widgetId = useRef(null);
2349
+ const scriptLoaded = useRef(false);
2350
+ useEffect(() => {
2351
+ if (!widgetRef.current || !siteKey)
2352
+ return;
2353
+ const loadTurnstile = () => {
2354
+ if (window.turnstile && widgetRef.current && !widgetId.current) {
2355
+ try {
2356
+ widgetId.current = window.turnstile.render(widgetRef.current, {
2357
+ sitekey: siteKey,
2358
+ callback: onSuccess,
2359
+ 'error-callback': onError,
2360
+ 'expired-callback': onExpire,
2361
+ theme,
2362
+ size,
2363
+ tabindex: tabIndex,
2364
+ });
2365
+ }
2366
+ catch (error) {
2367
+ console.error('Failed to render Turnstile widget:', error);
2368
+ onError?.();
2369
+ }
2370
+ }
2371
+ };
2372
+ // Check if Turnstile is already loaded
2373
+ if (window.turnstile) {
2374
+ loadTurnstile();
2375
+ }
2376
+ else if (!scriptLoaded.current) {
2377
+ // Load Turnstile script
2378
+ scriptLoaded.current = true;
2379
+ const script = document.createElement('script');
2380
+ script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
2381
+ script.async = true;
2382
+ script.defer = true;
2383
+ script.onload = loadTurnstile;
2384
+ script.onerror = () => {
2385
+ console.error('Failed to load Turnstile script');
2386
+ onError?.();
2387
+ };
2388
+ document.head.appendChild(script);
2389
+ }
2390
+ return () => {
2391
+ if (widgetId.current && window.turnstile) {
2392
+ try {
2393
+ window.turnstile.remove(widgetId.current);
2394
+ }
2395
+ catch (error) {
2396
+ console.error('Failed to remove Turnstile widget:', error);
2397
+ }
2398
+ widgetId.current = null;
2399
+ }
2400
+ };
2401
+ }, [siteKey, onSuccess, onError, onExpire, theme, size, tabIndex]);
2402
+ return jsxRuntimeExports.jsx("div", { ref: widgetRef, className: "cf-turnstile" });
2403
+ };
2404
+
2346
2405
  const MauticForm = ({ formId, title, description, className = '', form, onSubmit, onSuccess, onError, }) => {
2347
2406
  const [formData, setFormData] = useState({});
2348
2407
  const [errors, setErrors] = useState({});
2349
2408
  const [isSubmitting, setIsSubmitting] = useState(false);
2350
2409
  const [isSubmitted, setIsSubmitted] = useState(false);
2351
2410
  const [showSuccessMessage, setShowSuccessMessage] = useState(false);
2411
+ const [turnstileToken, setTurnstileToken] = useState(null);
2352
2412
  const submitMutation = useMauticFormSubmission();
2413
+ // Get Turnstile site key from environment
2414
+ const getTurnstilesiteKey = () => {
2415
+ // Check for Vite environment (browser)
2416
+ if (typeof window !== 'undefined' && window.import?.meta?.env) {
2417
+ return window.import.meta.env.VITE_TURNSTILE_SITE_KEY;
2418
+ }
2419
+ // Check for direct import.meta (Vite)
2420
+ try {
2421
+ // @ts-ignore - import.meta is a Vite-specific global
2422
+ if (typeof import.meta !== 'undefined' && import.meta.env) {
2423
+ // @ts-ignore
2424
+ return import.meta.env.VITE_TURNSTILE_SITE_KEY;
2425
+ }
2426
+ }
2427
+ catch (e) {
2428
+ // import.meta not available
2429
+ }
2430
+ return undefined;
2431
+ };
2432
+ const turnstilesiteKey = getTurnstilesiteKey();
2353
2433
  useEffect(() => {
2354
2434
  if (!form) {
2355
2435
  console.warn(`Form ${formId} not found`);
@@ -2408,6 +2488,11 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2408
2488
  if (!validateForm()) {
2409
2489
  return;
2410
2490
  }
2491
+ // Check Turnstile token if enabled
2492
+ if (turnstilesiteKey && !turnstileToken) {
2493
+ setErrors(prev => ({ ...prev, _turnstile: 'Please complete the verification' }));
2494
+ return;
2495
+ }
2411
2496
  setIsSubmitting(true);
2412
2497
  setErrors({});
2413
2498
  try {
@@ -2423,7 +2508,12 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2423
2508
  formId: parseInt(formId),
2424
2509
  fields: formData,
2425
2510
  returnUrl: window.location.href,
2426
- ...(derivedFormName ? { formName: derivedFormName } : {})
2511
+ ...(derivedFormName ? { formName: derivedFormName } : {}),
2512
+ ...(turnstileToken ? {
2513
+ headers: {
2514
+ 'cf-turnstile-response': turnstileToken
2515
+ }
2516
+ } : {})
2427
2517
  };
2428
2518
  // Call custom onSubmit if provided
2429
2519
  if (onSubmit) {
@@ -2512,7 +2602,23 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
2512
2602
  return (jsxRuntimeExports.jsxs("form", { className: `mautic-form ${className}`, onSubmit: handleSubmit, children: [(title || form.name) && (jsxRuntimeExports.jsxs("div", { className: "form-header", children: [jsxRuntimeExports.jsx("h3", { children: title || form.name }), (description || form.description) && (jsxRuntimeExports.jsx("p", { className: "form-description", children: description || form.description }))] })), jsxRuntimeExports.jsx("div", { className: "form-fields", children: form.fields
2513
2603
  // Filter out button/submit from field group; render them in actions
2514
2604
  .filter((field) => field.type !== 'button' && field.alias !== 'submit')
2515
- .map((field) => (jsxRuntimeExports.jsxs("div", { className: `form-field form-field-${field.type}`, children: [field.showLabel !== false && (jsxRuntimeExports.jsxs("label", { htmlFor: field.alias, className: "field-label", children: [field.label, field.isRequired && jsxRuntimeExports.jsx("span", { className: "required", children: "*" })] })), renderField(field), field.properties?.helpText && (jsxRuntimeExports.jsx("p", { className: "field-help", children: field.properties.helpText })), errors[field.alias] && (jsxRuntimeExports.jsx("p", { className: "field-error", children: errors[field.alias] }))] }, field.id))) }), jsxRuntimeExports.jsx("div", { className: "form-actions", children: jsxRuntimeExports.jsx("button", { type: "submit", disabled: isSubmitting, className: "submit-button", children: isSubmitting ? 'Submitting...' : 'Submit' }) }), submitMutation.error && (jsxRuntimeExports.jsx("div", { className: "form-error", children: jsxRuntimeExports.jsx("p", { children: "There was an error submitting the form. Please try again." }) }))] }));
2605
+ .map((field) => (jsxRuntimeExports.jsxs("div", { className: `form-field form-field-${field.type}`, children: [field.showLabel !== false && (jsxRuntimeExports.jsxs("label", { htmlFor: field.alias, className: "field-label", children: [field.label, field.isRequired && jsxRuntimeExports.jsx("span", { className: "required", children: "*" })] })), renderField(field), field.properties?.helpText && (jsxRuntimeExports.jsx("p", { className: "field-help", children: field.properties.helpText })), errors[field.alias] && (jsxRuntimeExports.jsx("p", { className: "field-error", children: errors[field.alias] }))] }, field.id))) }), turnstilesiteKey && (jsxRuntimeExports.jsxs("div", { className: "form-turnstile", children: [jsxRuntimeExports.jsx(TurnstileWidget, { siteKey: turnstilesiteKey, onSuccess: (token) => {
2606
+ setTurnstileToken(token);
2607
+ // Clear any turnstile error
2608
+ if (errors._turnstile) {
2609
+ setErrors(prev => {
2610
+ const next = { ...prev };
2611
+ delete next._turnstile;
2612
+ return next;
2613
+ });
2614
+ }
2615
+ }, onError: () => {
2616
+ setTurnstileToken(null);
2617
+ setErrors(prev => ({ ...prev, _turnstile: 'Verification failed. Please try again.' }));
2618
+ }, onExpire: () => {
2619
+ setTurnstileToken(null);
2620
+ setErrors(prev => ({ ...prev, _turnstile: 'Verification expired. Please verify again.' }));
2621
+ }, theme: "auto", size: "normal" }), errors._turnstile && (jsxRuntimeExports.jsx("p", { className: "field-error turnstile-error", children: errors._turnstile }))] })), jsxRuntimeExports.jsx("div", { className: "form-actions", children: jsxRuntimeExports.jsx("button", { type: "submit", disabled: isSubmitting || (!!turnstilesiteKey && !turnstileToken), className: "submit-button", children: isSubmitting ? 'Submitting...' : 'Submit' }) }), submitMutation.error && (jsxRuntimeExports.jsx("div", { className: "form-error", children: jsxRuntimeExports.jsx("p", { children: "There was an error submitting the form. Please try again." }) }))] }));
2516
2622
  };
2517
2623
 
2518
2624
  const MauticTracking = ({ enabled, mauticUrl, proxyUrl, children }) => {
@@ -3067,5 +3173,5 @@ const formatFormDataForSubmission = (formData) => {
3067
3173
  return formatted;
3068
3174
  };
3069
3175
 
3070
- export { MauticClient, MauticForm, MauticGenerator, MauticProvider, MauticService, MauticTracking, createMauticConfig, formatFormDataForSubmission, generateMauticData, getAllFieldTypes, getDataMetadata, getDefaultMauticConfig, getFormByAlias, getFormById, getFormFieldByAlias, getFormsByFieldType, getFormsByType, getFormsCountByStatus, getMauticConfigSummary, getMauticData, getPublishedForms, isDataLoaded, isFormDataValid, isMauticEnabled, isRequiredFieldValid, isValidEmail, isValidPhone, isValidUrl, loadMauticData, mauticService, mergeMauticConfig, sanitizeFormData, searchForms, setMauticClient, useMauticAddTags, useMauticAddToSegment, useMauticClient, useMauticConfig, useMauticContactByEmail, useMauticContactTags, useMauticContext, useMauticCreateContact, useMauticEvent, useMauticEventTracking, useMauticForm, useMauticFormSubmission, useMauticForms, useMauticRemoveFromSegment, useMauticRemoveTags, useMauticSegments, useMauticTags, useMauticTracking, useMauticUpdateContact, validateField, validateFormData, validateMauticConfig };
3176
+ export { MauticClient, MauticForm, MauticGenerator, MauticProvider, MauticService, MauticTracking, TurnstileWidget, createMauticConfig, formatFormDataForSubmission, generateMauticData, getAllFieldTypes, getDataMetadata, getDefaultMauticConfig, getFormByAlias, getFormById, getFormFieldByAlias, getFormsByFieldType, getFormsByType, getFormsCountByStatus, getMauticConfigSummary, getMauticData, getPublishedForms, isDataLoaded, isFormDataValid, isMauticEnabled, isRequiredFieldValid, isValidEmail, isValidPhone, isValidUrl, loadMauticData, mauticService, mergeMauticConfig, sanitizeFormData, searchForms, setMauticClient, useMauticAddTags, useMauticAddToSegment, useMauticClient, useMauticConfig, useMauticContactByEmail, useMauticContactTags, useMauticContext, useMauticCreateContact, useMauticEvent, useMauticEventTracking, useMauticForm, useMauticFormSubmission, useMauticForms, useMauticRemoveFromSegment, useMauticRemoveTags, useMauticSegments, useMauticTags, useMauticTracking, useMauticUpdateContact, validateField, validateFormData, validateMauticConfig };
3071
3177
  //# sourceMappingURL=index.esm.js.map