@saastro/forms 0.5.0 → 0.6.0
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 +64 -1
- package/dist/index.js +176 -2
- package/dist/index.js.map +1 -1
- package/package.json +10 -11
package/dist/index.d.ts
CHANGED
|
@@ -3025,6 +3025,69 @@ declare global {
|
|
|
3025
3025
|
*/
|
|
3026
3026
|
declare function recaptchaPlugin(config: RecaptchaPluginConfig): FormPlugin;
|
|
3027
3027
|
|
|
3028
|
+
/**
|
|
3029
|
+
* ============================================
|
|
3030
|
+
* TURNSTILE PLUGIN - Cloudflare Turnstile
|
|
3031
|
+
* ============================================
|
|
3032
|
+
*
|
|
3033
|
+
* Mirrors `recaptchaPlugin` but for Cloudflare Turnstile. Unlike
|
|
3034
|
+
* reCAPTCHA v3 (purely programmatic), Turnstile is widget-based: it must
|
|
3035
|
+
* be rendered into a DOM element. This plugin renders the widget in
|
|
3036
|
+
* explicit + `execution: 'execute'` mode (so it only challenges at submit
|
|
3037
|
+
* time) into a container it manages, captures the token via the success
|
|
3038
|
+
* callback, and attaches it to every submission via `transformValues`.
|
|
3039
|
+
*
|
|
3040
|
+
* The token field defaults to `_captchaToken` — the canonical field the
|
|
3041
|
+
* Hub submit helper (`createHubFormSubmit`) extracts and forwards to the
|
|
3042
|
+
* worker as `captchaToken`.
|
|
3043
|
+
*/
|
|
3044
|
+
interface TurnstilePluginConfig {
|
|
3045
|
+
/** Cloudflare Turnstile site key. */
|
|
3046
|
+
siteKey: string;
|
|
3047
|
+
/** Field name for the token in submitted values (default: '_captchaToken'). */
|
|
3048
|
+
tokenField?: string;
|
|
3049
|
+
/**
|
|
3050
|
+
* Widget appearance. 'interaction-only' (default) keeps it invisible
|
|
3051
|
+
* unless Cloudflare decides a challenge is needed — closest to the
|
|
3052
|
+
* reCAPTCHA v3 UX. 'always' renders a visible widget.
|
|
3053
|
+
*/
|
|
3054
|
+
appearance?: 'always' | 'execute' | 'interaction-only';
|
|
3055
|
+
/**
|
|
3056
|
+
* CSS selector for the element to render the widget into. Defaults to
|
|
3057
|
+
* `[data-saastro-turnstile]` (rendered inline by `HubForm`). If no such
|
|
3058
|
+
* element exists, the plugin creates a fixed, bottom-right container so
|
|
3059
|
+
* an interactive challenge can still surface.
|
|
3060
|
+
*/
|
|
3061
|
+
container?: string;
|
|
3062
|
+
}
|
|
3063
|
+
interface TurnstileApi {
|
|
3064
|
+
render: (el: HTMLElement | string, options: Record<string, unknown>) => string;
|
|
3065
|
+
execute: (widgetId?: string, options?: Record<string, unknown>) => void;
|
|
3066
|
+
reset: (widgetId?: string) => void;
|
|
3067
|
+
remove: (widgetId?: string) => void;
|
|
3068
|
+
getResponse: (widgetId?: string) => string | undefined;
|
|
3069
|
+
}
|
|
3070
|
+
declare global {
|
|
3071
|
+
interface Window {
|
|
3072
|
+
turnstile?: TurnstileApi;
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
/**
|
|
3076
|
+
* Cloudflare Turnstile plugin.
|
|
3077
|
+
*
|
|
3078
|
+
* @example
|
|
3079
|
+
* ```tsx
|
|
3080
|
+
* import { turnstilePlugin, PluginManager, FormBuilder } from '@saastro/forms';
|
|
3081
|
+
*
|
|
3082
|
+
* const pm = new PluginManager();
|
|
3083
|
+
* pm.register(turnstilePlugin({ siteKey: '0x4AAAAAAA...' }));
|
|
3084
|
+
* ```
|
|
3085
|
+
*
|
|
3086
|
+
* With `HubForm`, this is wired automatically when the form schema
|
|
3087
|
+
* declares `meta.captchaProvider === 'turnstile'`.
|
|
3088
|
+
*/
|
|
3089
|
+
declare function turnstilePlugin(config: TurnstilePluginConfig): FormPlugin;
|
|
3090
|
+
|
|
3028
3091
|
/**
|
|
3029
3092
|
* ============================================
|
|
3030
3093
|
* SHADCN/UI PRESET - Component Registry
|
|
@@ -3870,4 +3933,4 @@ declare function getFieldClass(formLayout?: {
|
|
|
3870
3933
|
*/
|
|
3871
3934
|
declare function getHiddenClasses(hidden?: Partial<Record<Breakpoint, 'visible' | 'hidden'>>): string;
|
|
3872
3935
|
|
|
3873
|
-
export { type AccordionContentProps, type AccordionItemProps, type AccordionProps, type AccordionTriggerProps, BUILD_METHODS, BUILTIN_RESOLVERS, type BaseFieldProps, type Breakpoint$1 as Breakpoint, type BuiltinTransform, type ButtonCardFieldProps, type ButtonCardOption, type ButtonCheckboxFieldProps, type ButtonConfig, type ButtonProps, type ButtonRadioFieldProps, COMMON_CLASSES, COMMON_METHODS, COMMON_STRINGS, type CalendarProps, type CheckboxFieldProps, type CheckboxGroupFieldProps, type CheckboxProps, type ColumnsValue, type ComboboxFieldProps, type CommandEmptyProps, type CommandFieldProps, type CommandGroupProps, type CommandInputProps, type CommandItemProps, type CommandListProps, type CommandProps, type ComponentName, type ComponentOverrides, ComponentProvider, type ComponentProviderProps, type ComponentRegistry, type ComponentRegistryInput, ComponentResolver, type ComponentResolverConfig, type Condition, type ConditionGroup, type ConditionOperator, type CreateHubFormSubmitOptions, type CurrencyFieldProps, type CustomSubmitAction, type CustomSubmitConfig, DEFAULT_HUB_URL, type DatabowlConfig, type DateFieldProps, type DateRangeFieldProps, type DefaultSubmitConfig, type DefinePlugin, type DialogContentProps, type DialogDescriptionProps, type DialogHeaderProps, type DialogProps, type DialogTitleProps, type DialogTriggerProps, type EmailProvider, type EmailSubmitAction, type EndpointConfig, FIELD_DEFAULTS, FieldBuilder, type FieldConfig, type FieldDescriptionProps, type FieldErrorProps, type FieldLabelProps, type FieldLayoutConfig, type FieldMapEntry, type FieldMapping, type FieldMappingConfig, type FieldProps, FieldRenderer, type FieldResolver, type FieldTransformFn, type Fields, type FileFieldProps, Form, FormBuilder, type FormButtonProps, type FormButtons, FormComponentsProvider, type FormComponentsProviderProps, type FormConfig, type FormControlProps, type FormFieldProps, type FormLayout, type FormPlugin, type FormProps, type FormRef, type FormStepsInfo, type GapValue, type GlobModules, type HiddenFieldProps, type HtmlFieldProps, type HttpAuthConfig, type HttpBodyConfig, type HttpEndpointConfig, type HttpRetryConfig, type HttpSubmitAction, HubForm, type HubFormProps, type InputGroupFieldProps, type InputOTPGroupProps, type InputOTPProps, type InputOTPSlotProps, type InputProps, type InputSize, type IntegrationSubmitAction, InternalComponentProvider, type InternalComponentProviderProps, type LabelProps, MissingComponentFallback, type MissingComponentFallbackProps, type NativeSelectFieldProps, type NativeSelectProps, OPTION_BASED_TYPES, type Option, type OtpFieldProps, type PartialComponentRegistry, PluginManager, type PopoverContentProps, type PopoverProps, type PopoverTriggerProps, type PropertyMapping, type RadioFieldProps, type RadioGroupItemProps, type RadioGroupProps, type RangeFieldProps, type RecaptchaConfig, type RecaptchaPluginConfig, type RepeaterFieldProps, type ResolvedComponents, SUSPENSE_CONFIG, type SchemaType, type SelectContentProps, type SelectFieldProps, type SelectItemProps, type SelectProps, type SelectTriggerProps, type SelectValueProps, type SeparatorProps, type SerializableFieldResolver, type SerializationHint, type SliderFieldProps, type SliderProps, type Step, type StepCondition, type StepInfo, type StepStatus, type Steps, StepsAccordion, StepsNavigation, StepsProgress, type SubmitAction, type SubmitActionCondition, type SubmitActionNode, type SubmitActionResult, type SubmitActionType, type SubmitActionsResult, type SubmitConfig, type SubmitConfirmationConfig, type SubmitExecutionConfig, type SubmitTrigger, type SubmitTriggerType, type SubmitType, type SwitchFieldProps, type SwitchGroupFieldProps, type SwitchProps, TYPE_SPECIFIC_PROPERTIES, type TestDataLocale, type TestDataOptions, type TextFieldProps, type TextareaFieldProps, type TextareaProps, type TooltipContentProps, type TooltipProps, type TooltipProviderProps, type TooltipTriggerProps, type UseSubmitConfirmationReturn, VALIDATION_METHODS, type ValidateComponentRegistry, type ValidationContext, type ValidationPresetMeta, type ValidationRules, type WebhookSubmitAction, analyticsPlugin, applyBuiltinTransform, applyFieldMapping, applyFieldMappingSync, applyFieldTransforms, applyTransform, autosavePlugin, compileValidationRules, configureComponents, coreComponents, createComponentRegistry, createHubFormSubmit, createMissingComponentPlaceholder, createShadcnRegistry, databowlAction, databowlPlugin, defaultSubmit, definePlugin, detectLocale, executeCustomAction, executeEmailAction, executeHttpAction, executeSubmitAction, executeSubmitActions, executeSubmitActionsByTrigger, executeWebhookAction, fieldTypeComponents, generateFieldValue, generateTestData, getActionsByTrigger, getAllKnownMethods, getAvailablePresets, getComponentResolver, getFieldClass, getFormGridClass, getHiddenClasses, getInstallCommand, getMinDelayMs, getMissingComponents, getRequiredComponents, globalPluginManager, groupMissingByPackage, iconVariants, iconVariantsConfig, inputVariants, inputVariantsConfig, isAdvancedMapping, isValidationRules, isZodSchema, localStoragePlugin, mergeComponentRegistries, parseGlobModules, pxToRem, recaptchaPlugin, registerPreset, resolvePreset, resolveValue, resolveValueSync, textareaVariants, textareaVariantsConfig, useComponentMode, useComponents, useComputedFields, useFormLayout, useFormState, useFormStepsInfo, useHasComponentProvider, useHiddenFieldResolvers, usePartialComponents, useRecaptcha, useSubmitActionTriggers, useSubmitConfirmation, withComponents };
|
|
3936
|
+
export { type AccordionContentProps, type AccordionItemProps, type AccordionProps, type AccordionTriggerProps, BUILD_METHODS, BUILTIN_RESOLVERS, type BaseFieldProps, type Breakpoint$1 as Breakpoint, type BuiltinTransform, type ButtonCardFieldProps, type ButtonCardOption, type ButtonCheckboxFieldProps, type ButtonConfig, type ButtonProps, type ButtonRadioFieldProps, COMMON_CLASSES, COMMON_METHODS, COMMON_STRINGS, type CalendarProps, type CheckboxFieldProps, type CheckboxGroupFieldProps, type CheckboxProps, type ColumnsValue, type ComboboxFieldProps, type CommandEmptyProps, type CommandFieldProps, type CommandGroupProps, type CommandInputProps, type CommandItemProps, type CommandListProps, type CommandProps, type ComponentName, type ComponentOverrides, ComponentProvider, type ComponentProviderProps, type ComponentRegistry, type ComponentRegistryInput, ComponentResolver, type ComponentResolverConfig, type Condition, type ConditionGroup, type ConditionOperator, type CreateHubFormSubmitOptions, type CurrencyFieldProps, type CustomSubmitAction, type CustomSubmitConfig, DEFAULT_HUB_URL, type DatabowlConfig, type DateFieldProps, type DateRangeFieldProps, type DefaultSubmitConfig, type DefinePlugin, type DialogContentProps, type DialogDescriptionProps, type DialogHeaderProps, type DialogProps, type DialogTitleProps, type DialogTriggerProps, type EmailProvider, type EmailSubmitAction, type EndpointConfig, FIELD_DEFAULTS, FieldBuilder, type FieldConfig, type FieldDescriptionProps, type FieldErrorProps, type FieldLabelProps, type FieldLayoutConfig, type FieldMapEntry, type FieldMapping, type FieldMappingConfig, type FieldProps, FieldRenderer, type FieldResolver, type FieldTransformFn, type Fields, type FileFieldProps, Form, FormBuilder, type FormButtonProps, type FormButtons, FormComponentsProvider, type FormComponentsProviderProps, type FormConfig, type FormControlProps, type FormFieldProps, type FormLayout, type FormPlugin, type FormProps, type FormRef, type FormStepsInfo, type GapValue, type GlobModules, type HiddenFieldProps, type HtmlFieldProps, type HttpAuthConfig, type HttpBodyConfig, type HttpEndpointConfig, type HttpRetryConfig, type HttpSubmitAction, HubForm, type HubFormProps, type InputGroupFieldProps, type InputOTPGroupProps, type InputOTPProps, type InputOTPSlotProps, type InputProps, type InputSize, type IntegrationSubmitAction, InternalComponentProvider, type InternalComponentProviderProps, type LabelProps, MissingComponentFallback, type MissingComponentFallbackProps, type NativeSelectFieldProps, type NativeSelectProps, OPTION_BASED_TYPES, type Option, type OtpFieldProps, type PartialComponentRegistry, PluginManager, type PopoverContentProps, type PopoverProps, type PopoverTriggerProps, type PropertyMapping, type RadioFieldProps, type RadioGroupItemProps, type RadioGroupProps, type RangeFieldProps, type RecaptchaConfig, type RecaptchaPluginConfig, type RepeaterFieldProps, type ResolvedComponents, SUSPENSE_CONFIG, type SchemaType, type SelectContentProps, type SelectFieldProps, type SelectItemProps, type SelectProps, type SelectTriggerProps, type SelectValueProps, type SeparatorProps, type SerializableFieldResolver, type SerializationHint, type SliderFieldProps, type SliderProps, type Step, type StepCondition, type StepInfo, type StepStatus, type Steps, StepsAccordion, StepsNavigation, StepsProgress, type SubmitAction, type SubmitActionCondition, type SubmitActionNode, type SubmitActionResult, type SubmitActionType, type SubmitActionsResult, type SubmitConfig, type SubmitConfirmationConfig, type SubmitExecutionConfig, type SubmitTrigger, type SubmitTriggerType, type SubmitType, type SwitchFieldProps, type SwitchGroupFieldProps, type SwitchProps, TYPE_SPECIFIC_PROPERTIES, type TestDataLocale, type TestDataOptions, type TextFieldProps, type TextareaFieldProps, type TextareaProps, type TooltipContentProps, type TooltipProps, type TooltipProviderProps, type TooltipTriggerProps, type TurnstilePluginConfig, type UseSubmitConfirmationReturn, VALIDATION_METHODS, type ValidateComponentRegistry, type ValidationContext, type ValidationPresetMeta, type ValidationRules, type WebhookSubmitAction, analyticsPlugin, applyBuiltinTransform, applyFieldMapping, applyFieldMappingSync, applyFieldTransforms, applyTransform, autosavePlugin, compileValidationRules, configureComponents, coreComponents, createComponentRegistry, createHubFormSubmit, createMissingComponentPlaceholder, createShadcnRegistry, databowlAction, databowlPlugin, defaultSubmit, definePlugin, detectLocale, executeCustomAction, executeEmailAction, executeHttpAction, executeSubmitAction, executeSubmitActions, executeSubmitActionsByTrigger, executeWebhookAction, fieldTypeComponents, generateFieldValue, generateTestData, getActionsByTrigger, getAllKnownMethods, getAvailablePresets, getComponentResolver, getFieldClass, getFormGridClass, getHiddenClasses, getInstallCommand, getMinDelayMs, getMissingComponents, getRequiredComponents, globalPluginManager, groupMissingByPackage, iconVariants, iconVariantsConfig, inputVariants, inputVariantsConfig, isAdvancedMapping, isValidationRules, isZodSchema, localStoragePlugin, mergeComponentRegistries, parseGlobModules, pxToRem, recaptchaPlugin, registerPreset, resolvePreset, resolveValue, resolveValueSync, textareaVariants, textareaVariantsConfig, turnstilePlugin, useComponentMode, useComponents, useComputedFields, useFormLayout, useFormState, useFormStepsInfo, useHasComponentProvider, useHiddenFieldResolvers, usePartialComponents, useRecaptcha, useSubmitActionTriggers, useSubmitConfirmation, withComponents };
|
package/dist/index.js
CHANGED
|
@@ -6071,6 +6071,156 @@ function recaptchaPlugin(config) {
|
|
|
6071
6071
|
});
|
|
6072
6072
|
}
|
|
6073
6073
|
|
|
6074
|
+
// src/plugins/turnstile.ts
|
|
6075
|
+
var SCRIPT_SRC = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";
|
|
6076
|
+
var TOKEN_TIMEOUT_MS = 2e4;
|
|
6077
|
+
function waitForTurnstile(timeoutMs = 1e4) {
|
|
6078
|
+
return new Promise((resolve, reject) => {
|
|
6079
|
+
if (typeof window === "undefined") {
|
|
6080
|
+
reject(new Error("turnstile: no window"));
|
|
6081
|
+
return;
|
|
6082
|
+
}
|
|
6083
|
+
if (window.turnstile) {
|
|
6084
|
+
resolve(window.turnstile);
|
|
6085
|
+
return;
|
|
6086
|
+
}
|
|
6087
|
+
const start = Date.now();
|
|
6088
|
+
const tick = () => {
|
|
6089
|
+
if (window.turnstile) {
|
|
6090
|
+
resolve(window.turnstile);
|
|
6091
|
+
} else if (Date.now() - start > timeoutMs) {
|
|
6092
|
+
reject(new Error("turnstile: script did not load"));
|
|
6093
|
+
} else {
|
|
6094
|
+
setTimeout(tick, 100);
|
|
6095
|
+
}
|
|
6096
|
+
};
|
|
6097
|
+
tick();
|
|
6098
|
+
});
|
|
6099
|
+
}
|
|
6100
|
+
function turnstilePlugin(config) {
|
|
6101
|
+
const {
|
|
6102
|
+
siteKey,
|
|
6103
|
+
tokenField = "_captchaToken",
|
|
6104
|
+
appearance = "interaction-only",
|
|
6105
|
+
container
|
|
6106
|
+
} = config;
|
|
6107
|
+
let scriptElement = null;
|
|
6108
|
+
let createdContainer = null;
|
|
6109
|
+
let widgetId;
|
|
6110
|
+
let lastToken = null;
|
|
6111
|
+
let pending = null;
|
|
6112
|
+
const resolveContainer = () => {
|
|
6113
|
+
if (container) {
|
|
6114
|
+
const found = document.querySelector(container);
|
|
6115
|
+
if (found) return found;
|
|
6116
|
+
}
|
|
6117
|
+
const byData = document.querySelector("[data-saastro-turnstile]");
|
|
6118
|
+
if (byData) return byData;
|
|
6119
|
+
if (!createdContainer) {
|
|
6120
|
+
createdContainer = document.createElement("div");
|
|
6121
|
+
createdContainer.setAttribute("data-saastro-turnstile-fallback", "");
|
|
6122
|
+
createdContainer.style.position = "fixed";
|
|
6123
|
+
createdContainer.style.bottom = "12px";
|
|
6124
|
+
createdContainer.style.right = "12px";
|
|
6125
|
+
createdContainer.style.zIndex = "2147483647";
|
|
6126
|
+
document.body.appendChild(createdContainer);
|
|
6127
|
+
}
|
|
6128
|
+
return createdContainer;
|
|
6129
|
+
};
|
|
6130
|
+
const ensureWidget = async () => {
|
|
6131
|
+
const api = await waitForTurnstile();
|
|
6132
|
+
if (widgetId === void 0) {
|
|
6133
|
+
const el = resolveContainer();
|
|
6134
|
+
widgetId = api.render(el, {
|
|
6135
|
+
sitekey: siteKey,
|
|
6136
|
+
appearance,
|
|
6137
|
+
execution: "execute",
|
|
6138
|
+
callback: (token) => {
|
|
6139
|
+
lastToken = token;
|
|
6140
|
+
pending?.resolve(token);
|
|
6141
|
+
pending = null;
|
|
6142
|
+
},
|
|
6143
|
+
"error-callback": () => {
|
|
6144
|
+
pending?.reject(new Error("turnstile: challenge failed"));
|
|
6145
|
+
pending = null;
|
|
6146
|
+
return true;
|
|
6147
|
+
},
|
|
6148
|
+
"expired-callback": () => {
|
|
6149
|
+
lastToken = null;
|
|
6150
|
+
}
|
|
6151
|
+
});
|
|
6152
|
+
}
|
|
6153
|
+
return api;
|
|
6154
|
+
};
|
|
6155
|
+
return definePlugin({
|
|
6156
|
+
name: "turnstile",
|
|
6157
|
+
version: "1.0.0",
|
|
6158
|
+
description: "Cloudflare Turnstile \u2014 widget render and token generation",
|
|
6159
|
+
onFormInit() {
|
|
6160
|
+
if (typeof window === "undefined") return;
|
|
6161
|
+
if (!window.turnstile && !document.querySelector('script[src*="turnstile/v0/api.js"]')) {
|
|
6162
|
+
scriptElement = document.createElement("script");
|
|
6163
|
+
scriptElement.src = SCRIPT_SRC;
|
|
6164
|
+
scriptElement.async = true;
|
|
6165
|
+
scriptElement.defer = true;
|
|
6166
|
+
document.body.appendChild(scriptElement);
|
|
6167
|
+
}
|
|
6168
|
+
void ensureWidget().catch(() => {
|
|
6169
|
+
});
|
|
6170
|
+
},
|
|
6171
|
+
async transformValues(values) {
|
|
6172
|
+
if (typeof window === "undefined") return values;
|
|
6173
|
+
try {
|
|
6174
|
+
const api = await ensureWidget();
|
|
6175
|
+
const token = await new Promise((resolve, reject) => {
|
|
6176
|
+
pending = { resolve, reject };
|
|
6177
|
+
const timer = setTimeout(() => {
|
|
6178
|
+
if (pending) {
|
|
6179
|
+
pending = null;
|
|
6180
|
+
reject(new Error("turnstile: token timeout"));
|
|
6181
|
+
}
|
|
6182
|
+
}, TOKEN_TIMEOUT_MS);
|
|
6183
|
+
const wrappedResolve = (t) => {
|
|
6184
|
+
clearTimeout(timer);
|
|
6185
|
+
resolve(t);
|
|
6186
|
+
};
|
|
6187
|
+
const wrappedReject = (e) => {
|
|
6188
|
+
clearTimeout(timer);
|
|
6189
|
+
reject(e);
|
|
6190
|
+
};
|
|
6191
|
+
pending = { resolve: wrappedResolve, reject: wrappedReject };
|
|
6192
|
+
lastToken = null;
|
|
6193
|
+
api.reset(widgetId);
|
|
6194
|
+
api.execute(widgetId);
|
|
6195
|
+
});
|
|
6196
|
+
return { ...values, [tokenField]: token };
|
|
6197
|
+
} catch (error) {
|
|
6198
|
+
console.error("turnstilePlugin: failed to get token:", error);
|
|
6199
|
+
return values;
|
|
6200
|
+
}
|
|
6201
|
+
},
|
|
6202
|
+
cleanup() {
|
|
6203
|
+
if (typeof window !== "undefined" && window.turnstile && widgetId !== void 0) {
|
|
6204
|
+
try {
|
|
6205
|
+
window.turnstile.remove(widgetId);
|
|
6206
|
+
} catch {
|
|
6207
|
+
}
|
|
6208
|
+
}
|
|
6209
|
+
widgetId = void 0;
|
|
6210
|
+
lastToken = null;
|
|
6211
|
+
pending = null;
|
|
6212
|
+
if (createdContainer?.parentNode) {
|
|
6213
|
+
createdContainer.parentNode.removeChild(createdContainer);
|
|
6214
|
+
createdContainer = null;
|
|
6215
|
+
}
|
|
6216
|
+
if (scriptElement?.parentNode) {
|
|
6217
|
+
scriptElement.parentNode.removeChild(scriptElement);
|
|
6218
|
+
scriptElement = null;
|
|
6219
|
+
}
|
|
6220
|
+
}
|
|
6221
|
+
});
|
|
6222
|
+
}
|
|
6223
|
+
|
|
6074
6224
|
// src/presets/shadcn.ts
|
|
6075
6225
|
function createComponentRegistry(components) {
|
|
6076
6226
|
return {
|
|
@@ -6901,6 +7051,13 @@ function createHubFormSubmit(opts) {
|
|
|
6901
7051
|
// src/components/HubForm.tsx
|
|
6902
7052
|
import { useEffect as useEffect8, useMemo as useMemo7, useState as useState5 } from "react";
|
|
6903
7053
|
import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
7054
|
+
function readCaptchaMeta(schema) {
|
|
7055
|
+
const meta = schema.meta;
|
|
7056
|
+
return {
|
|
7057
|
+
captchaProvider: meta?.captchaProvider,
|
|
7058
|
+
captchaSiteKey: meta?.captchaSiteKey
|
|
7059
|
+
};
|
|
7060
|
+
}
|
|
6904
7061
|
function isRenderableSchema(value) {
|
|
6905
7062
|
if (!value || typeof value !== "object") return false;
|
|
6906
7063
|
const schema = value;
|
|
@@ -6970,6 +7127,18 @@ function HubForm({
|
|
|
6970
7127
|
}
|
|
6971
7128
|
};
|
|
6972
7129
|
}, [hubUrl, siteId, formSlug, onSuccess, onError]);
|
|
7130
|
+
const captcha = useMemo7(() => {
|
|
7131
|
+
if (state.status !== "ready") return void 0;
|
|
7132
|
+
const { captchaProvider, captchaSiteKey } = readCaptchaMeta(state.schema);
|
|
7133
|
+
if (!captchaProvider || !captchaSiteKey) return void 0;
|
|
7134
|
+
const pm = new PluginManager();
|
|
7135
|
+
if (captchaProvider === "turnstile") {
|
|
7136
|
+
pm.register(turnstilePlugin({ siteKey: captchaSiteKey, tokenField: "_captchaToken" }));
|
|
7137
|
+
} else {
|
|
7138
|
+
pm.register(recaptchaPlugin({ siteKey: captchaSiteKey, tokenField: "_captchaToken" }));
|
|
7139
|
+
}
|
|
7140
|
+
return { pm, provider: captchaProvider };
|
|
7141
|
+
}, [state]);
|
|
6973
7142
|
if (state.status === "loading") {
|
|
6974
7143
|
return loadingFallback ?? /* @__PURE__ */ jsx14("div", { "data-saastro-hubform-loading": true, style: loadingStyle, children: "Loading\u2026" });
|
|
6975
7144
|
}
|
|
@@ -6990,9 +7159,13 @@ function HubForm({
|
|
|
6990
7159
|
}
|
|
6991
7160
|
const config = {
|
|
6992
7161
|
...state.schema,
|
|
6993
|
-
submit: wrappedSubmit
|
|
7162
|
+
submit: wrappedSubmit,
|
|
7163
|
+
...captcha ? { pluginManager: captcha.pm } : {}
|
|
6994
7164
|
};
|
|
6995
|
-
return /* @__PURE__ */
|
|
7165
|
+
return /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
7166
|
+
/* @__PURE__ */ jsx14(Form, { ...formProps, config }),
|
|
7167
|
+
captcha?.provider === "turnstile" ? /* @__PURE__ */ jsx14("div", { "data-saastro-turnstile": true }) : null
|
|
7168
|
+
] });
|
|
6996
7169
|
}
|
|
6997
7170
|
var loadingStyle = {
|
|
6998
7171
|
padding: "2rem 1rem",
|
|
@@ -7332,6 +7505,7 @@ export {
|
|
|
7332
7505
|
resolveValueSync,
|
|
7333
7506
|
textareaVariants,
|
|
7334
7507
|
textareaVariantsConfig,
|
|
7508
|
+
turnstilePlugin,
|
|
7335
7509
|
useComponentMode,
|
|
7336
7510
|
useComponents,
|
|
7337
7511
|
useComputedFields,
|