@createlex/onetapforms-sdk 1.2.0 → 1.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
@@ -1,5 +1,6 @@
1
1
  export { OneTapForms, default } from './sdk';
2
- export type { OneTapFormsConfig, RequestOptions, CompletionResult } from './types';
2
+ export type { OneTapFormsConfig, RequestOptions, CompletionResult, AutofillPreviewOptions, AutofillPreviewResult, } from './types';
3
+ export { otfFieldAttr, collectMappedFields, previewAutofill } from './autofill';
3
4
  /**
4
5
  * Create and show a QR modal
5
6
  */
package/dist/index.esm.js CHANGED
@@ -159,6 +159,58 @@ var sdk = /*#__PURE__*/Object.freeze({
159
159
  default: OneTapForms
160
160
  });
161
161
 
162
+ /**
163
+ * Helper to attach the canonical mapping attribute to a DOM element.
164
+ */
165
+ function otfFieldAttr(canonicalName) {
166
+ return { 'data-otf-field': canonicalName };
167
+ }
168
+ /**
169
+ * Collects all elements with a data-otf-field attribute.
170
+ * Returns the canonical name and the element reference.
171
+ */
172
+ function collectMappedFields(root = document) {
173
+ if (typeof document === 'undefined')
174
+ return [];
175
+ const nodes = Array.from(root.querySelectorAll('[data-otf-field]'));
176
+ return nodes
177
+ .map((el) => {
178
+ const name = el.getAttribute('data-otf-field');
179
+ return name ? { name, element: el } : null;
180
+ })
181
+ .filter((item) => Boolean(item));
182
+ }
183
+ /**
184
+ * Preview autofill values from the backend without mutating the DOM.
185
+ * The caller is responsible for applying values to inputs after user consent.
186
+ */
187
+ async function previewAutofill(options) {
188
+ const apiUrl = options.apiUrl || 'https://api.createlex.com/api/onetapforms/autofill/preview';
189
+ const payload = {
190
+ fields: options.fields || null,
191
+ formTemplate: options.formTemplate,
192
+ };
193
+ const headers = {
194
+ 'Content-Type': 'application/json',
195
+ };
196
+ if (options.token) {
197
+ headers['Authorization'] = `Bearer ${options.token}`;
198
+ }
199
+ if (options.userId) {
200
+ headers['x-user-id'] = options.userId;
201
+ }
202
+ const response = await fetch(apiUrl, {
203
+ method: 'POST',
204
+ headers,
205
+ body: JSON.stringify(payload),
206
+ });
207
+ if (!response.ok) {
208
+ const text = await response.text();
209
+ throw new Error(`Autofill preview failed: ${response.status} ${text}`);
210
+ }
211
+ return response.json();
212
+ }
213
+
162
214
  // Export the OneTapForms class and types
163
215
  // Widget auto-initialization for CDN/script tag usage
164
216
  // This runs automatically when loaded via <script> tag
@@ -435,5 +487,5 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
435
487
  }
436
488
  }
437
489
 
438
- export { OneTapForms, OneTapForms as default, initWidgets, showQRModal };
490
+ export { OneTapForms, collectMappedFields, OneTapForms as default, initWidgets, otfFieldAttr, previewAutofill, showQRModal };
439
491
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/sdk.ts","../src/index.ts"],"sourcesContent":["import type { OneTapFormsConfig, RequestOptions, CompletionResult } from './types';\nimport { OneTapForms as OneTapFormsImpl } from './onetapforms.js';\n\n/**\n * OneTapForms SDK class for secure, biometric-authenticated form completion\n */\nexport class OneTapForms {\n private instance: any;\n\n constructor(config: OneTapFormsConfig) {\n this.instance = new OneTapFormsImpl(config);\n }\n\n /**\n * Create a form completion request\n */\n async request(options: RequestOptions): Promise<void> {\n return this.instance.request(options);\n }\n\n /**\n * Cancel active polling (useful for cleanup)\n */\n cancelPolling(): void {\n return this.instance.cancelPolling();\n }\n\n /**\n * Handle callback from redirect flow\n * Call this when user returns to your site with token in URL\n */\n handleCallback(): CompletionResult | null {\n return this.instance.handleCallback();\n }\n\n /**\n * Exchange token for user data (server-side only!)\n * This should be called from your backend, not the browser\n */\n async exchangeToken(token: string): Promise<any> {\n return this.instance.exchangeToken(token);\n }\n\n /**\n * Get the App Store URL for downloading OneTapForms app\n * Use this to encourage users to download the app for faster form completion\n */\n getAppDownloadUrl(): string {\n return 'https://apps.apple.com/app/onetapforms';\n }\n\n /**\n * Show a prompt encouraging users to download the OneTapForms app\n * This helps developers get faster form completion and better conversion rates\n *\n * @param options Customization options for the prompt\n */\n showDownloadPrompt(options?: {\n title?: string;\n message?: string;\n buttonText?: string;\n onDismiss?: () => void;\n }): void {\n if (typeof window === 'undefined') {\n return; // Server-side, do nothing\n }\n\n const title = options?.title || 'Download OneTapForms for Faster Form Completion';\n const message = options?.message ||\n 'Complete forms in seconds with one tap! Download the OneTapForms app to instantly fill forms using Face ID/Touch ID.';\n const buttonText = options?.buttonText || 'Download App';\n const appUrl = this.getAppDownloadUrl();\n\n // Create a simple modal/prompt\n const modal = document.createElement('div');\n modal.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n `;\n\n const content = document.createElement('div');\n content.style.cssText = `\n background: white;\n padding: 24px;\n border-radius: 12px;\n max-width: 400px;\n margin: 20px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n `;\n\n const titleEl = document.createElement('h3');\n titleEl.textContent = title;\n titleEl.style.cssText = `\n margin: 0 0 12px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n `;\n\n const messageEl = document.createElement('p');\n messageEl.textContent = message;\n messageEl.style.cssText = `\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #666;\n line-height: 1.5;\n `;\n\n const buttonContainer = document.createElement('div');\n buttonContainer.style.cssText = `\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n `;\n\n const dismissBtn = document.createElement('button');\n dismissBtn.textContent = 'Maybe Later';\n dismissBtn.style.cssText = `\n padding: 10px 20px;\n border: 1px solid #ddd;\n background: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n color: #666;\n `;\n dismissBtn.onclick = () => {\n document.body.removeChild(modal);\n if (options?.onDismiss) {\n options.onDismiss();\n }\n };\n\n const downloadBtn = document.createElement('button');\n downloadBtn.textContent = buttonText;\n downloadBtn.style.cssText = `\n padding: 10px 20px;\n border: none;\n background: #007AFF;\n color: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n `;\n downloadBtn.onclick = () => {\n window.open(appUrl, '_blank');\n document.body.removeChild(modal);\n };\n\n buttonContainer.appendChild(dismissBtn);\n buttonContainer.appendChild(downloadBtn);\n\n content.appendChild(titleEl);\n content.appendChild(messageEl);\n content.appendChild(buttonContainer);\n modal.appendChild(content);\n\n // Close on background click\n modal.onclick = (e) => {\n if (e.target === modal) {\n document.body.removeChild(modal);\n if (options?.onDismiss) {\n options.onDismiss();\n }\n }\n };\n\n document.body.appendChild(modal);\n }\n}\n\nexport default OneTapForms;\n","// Export the OneTapForms class and types\nexport { OneTapForms, default } from './sdk';\nexport type {\n OneTapFormsConfig,\n RequestOptions,\n CompletionResult\n} from './types';\n\n// Widget auto-initialization for CDN/script tag usage\n// This runs automatically when loaded via <script> tag\n\n/**\n * Built-in QR Modal styles (CSS-in-JS, no external CSS required)\n */\nconst MODAL_STYLES = `\n .onetapforms-modal {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n .onetapforms-modal.active {\n opacity: 1;\n }\n .onetapforms-modal-content {\n background: white;\n padding: 32px;\n border-radius: 16px;\n max-width: 360px;\n width: 90%;\n text-align: center;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n transform: scale(0.95);\n transition: transform 0.2s ease;\n }\n .onetapforms-modal.active .onetapforms-modal-content {\n transform: scale(1);\n }\n .onetapforms-modal-title {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n }\n .onetapforms-modal-subtitle {\n margin: 0 0 24px 0;\n font-size: 14px;\n color: #666;\n }\n .onetapforms-qr-container {\n background: #f5f5f5;\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 20px;\n }\n .onetapforms-qr-container img {\n max-width: 100%;\n height: auto;\n }\n .onetapforms-status {\n font-size: 13px;\n color: #888;\n margin-bottom: 16px;\n }\n .onetapforms-close-btn {\n background: #f0f0f0;\n border: none;\n padding: 10px 24px;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: #333;\n transition: background 0.15s;\n }\n .onetapforms-close-btn:hover {\n background: #e0e0e0;\n }\n .onetapforms-spinner {\n width: 200px;\n height: 200px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .onetapforms-spinner::after {\n content: '';\n width: 40px;\n height: 40px;\n border: 3px solid #e0e0e0;\n border-top-color: #007AFF;\n border-radius: 50%;\n animation: onetapforms-spin 0.8s linear infinite;\n }\n @keyframes onetapforms-spin {\n to { transform: rotate(360deg); }\n }\n`;\n\n/**\n * Inject modal styles into the page (once)\n */\nfunction injectStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.getElementById('onetapforms-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'onetapforms-styles';\n style.textContent = MODAL_STYLES;\n document.head.appendChild(style);\n}\n\n/**\n * Create and show a QR modal\n */\nfunction showQRModal(options: {\n title?: string;\n subtitle?: string;\n onClose?: () => void;\n}): {\n setQR: (qrDataUrl: string) => void;\n setStatus: (status: string) => void;\n close: () => void;\n} {\n injectStyles();\n\n const modal = document.createElement('div');\n modal.className = 'onetapforms-modal';\n modal.innerHTML = `\n <div class=\"onetapforms-modal-content\">\n <h3 class=\"onetapforms-modal-title\">${options.title || 'Scan to Complete'}</h3>\n <p class=\"onetapforms-modal-subtitle\">${options.subtitle || 'Scan with your OneTapForms app'}</p>\n <div class=\"onetapforms-qr-container\">\n <div class=\"onetapforms-spinner\"></div>\n </div>\n <p class=\"onetapforms-status\">Waiting for scan...</p>\n <button class=\"onetapforms-close-btn\">Cancel</button>\n </div>\n `;\n\n const qrContainer = modal.querySelector('.onetapforms-qr-container')!;\n const statusEl = modal.querySelector('.onetapforms-status')!;\n const closeBtn = modal.querySelector('.onetapforms-close-btn')!;\n\n const close = () => {\n modal.classList.remove('active');\n setTimeout(() => modal.remove(), 200);\n if (options.onClose) options.onClose();\n };\n\n closeBtn.addEventListener('click', close);\n modal.addEventListener('click', (e) => {\n if (e.target === modal) close();\n });\n\n document.body.appendChild(modal);\n // Trigger animation\n requestAnimationFrame(() => modal.classList.add('active'));\n\n return {\n setQR: (qrDataUrl: string) => {\n qrContainer.innerHTML = `<img src=\"${qrDataUrl}\" alt=\"QR Code\" />`;\n },\n setStatus: (status: string) => {\n statusEl.textContent = status;\n },\n close\n };\n}\n\n/**\n * Initialize widget elements with data-onetapforms attribute\n */\nfunction initWidgets(): void {\n if (typeof document === 'undefined') return;\n\n const widgets = document.querySelectorAll<HTMLElement>('[data-onetapforms]');\n\n widgets.forEach((element) => {\n // Skip if already initialized\n if (element.dataset.onetapformsInit === 'true') return;\n element.dataset.onetapformsInit = 'true';\n\n const clientId = element.dataset.clientId;\n const clientSecret = element.dataset.clientSecret;\n const purpose = element.dataset.purpose || 'Complete form';\n const bundles = element.dataset.bundles?.split(',').map(b => b.trim()) || ['basic'];\n const formId = element.dataset.formId;\n const apiUrl = element.dataset.apiUrl;\n\n if (!clientId) {\n console.error('[OneTapForms] Missing data-client-id attribute');\n return;\n }\n\n // Import OneTapForms dynamically to avoid circular deps\n import('./sdk').then(({ OneTapForms }) => {\n const sdk = new OneTapForms({\n clientId,\n clientSecret,\n apiUrl\n });\n\n element.addEventListener('click', async (e) => {\n e.preventDefault();\n\n let modal: ReturnType<typeof showQRModal> | null = null;\n\n try {\n await sdk.request({\n purpose,\n bundles,\n onQRReady: (qrDataUrl) => {\n modal = showQRModal({\n title: 'Scan with OneTapForms',\n subtitle: purpose,\n onClose: () => sdk.cancelPolling()\n });\n modal.setQR(qrDataUrl);\n },\n onComplete: (result) => {\n if (modal) {\n modal.setStatus('Complete!');\n setTimeout(() => modal?.close(), 500);\n }\n\n // Dispatch custom event with result\n const event = new CustomEvent('onetapforms:complete', {\n bubbles: true,\n detail: result\n });\n element.dispatchEvent(event);\n\n // Auto-inject token into form if formId is specified\n if (formId) {\n const form = document.getElementById(formId) as HTMLFormElement;\n if (form) {\n let tokenInput = form.querySelector('input[name=\"onetapforms_token\"]') as HTMLInputElement;\n if (!tokenInput) {\n tokenInput = document.createElement('input');\n tokenInput.type = 'hidden';\n tokenInput.name = 'onetapforms_token';\n form.appendChild(tokenInput);\n }\n tokenInput.value = result.token;\n }\n }\n },\n onError: (error) => {\n if (modal) modal.close();\n\n const event = new CustomEvent('onetapforms:error', {\n bubbles: true,\n detail: { error }\n });\n element.dispatchEvent(event);\n }\n });\n } catch (error) {\n console.error('[OneTapForms] Request failed:', error);\n\n const event = new CustomEvent('onetapforms:error', {\n bubbles: true,\n detail: { error }\n });\n element.dispatchEvent(event);\n }\n });\n });\n });\n}\n\n// Auto-initialize on DOM ready (for UMD/script tag usage)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initWidgets);\n } else {\n // DOM already ready\n initWidgets();\n }\n\n // Also observe for dynamically added elements\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.addedNodes.length) {\n initWidgets();\n }\n }\n });\n\n if (document.body) {\n observer.observe(document.body, { childList: true, subtree: true });\n } else {\n document.addEventListener('DOMContentLoaded', () => {\n observer.observe(document.body, { childList: true, subtree: true });\n });\n }\n}\n\n// Export widget utilities for advanced usage\nexport { initWidgets, showQRModal };\n"],"names":["OneTapFormsImpl"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/sdk.ts","../src/autofill.ts","../src/index.ts"],"sourcesContent":["import type { OneTapFormsConfig, RequestOptions, CompletionResult } from './types';\nimport { OneTapForms as OneTapFormsImpl } from './onetapforms.js';\n\n/**\n * OneTapForms SDK class for secure, biometric-authenticated form completion\n */\nexport class OneTapForms {\n private instance: any;\n\n constructor(config: OneTapFormsConfig) {\n this.instance = new OneTapFormsImpl(config);\n }\n\n /**\n * Create a form completion request\n */\n async request(options: RequestOptions): Promise<void> {\n return this.instance.request(options);\n }\n\n /**\n * Cancel active polling (useful for cleanup)\n */\n cancelPolling(): void {\n return this.instance.cancelPolling();\n }\n\n /**\n * Handle callback from redirect flow\n * Call this when user returns to your site with token in URL\n */\n handleCallback(): CompletionResult | null {\n return this.instance.handleCallback();\n }\n\n /**\n * Exchange token for user data (server-side only!)\n * This should be called from your backend, not the browser\n */\n async exchangeToken(token: string): Promise<any> {\n return this.instance.exchangeToken(token);\n }\n\n /**\n * Get the App Store URL for downloading OneTapForms app\n * Use this to encourage users to download the app for faster form completion\n */\n getAppDownloadUrl(): string {\n return 'https://apps.apple.com/app/onetapforms';\n }\n\n /**\n * Show a prompt encouraging users to download the OneTapForms app\n * This helps developers get faster form completion and better conversion rates\n *\n * @param options Customization options for the prompt\n */\n showDownloadPrompt(options?: {\n title?: string;\n message?: string;\n buttonText?: string;\n onDismiss?: () => void;\n }): void {\n if (typeof window === 'undefined') {\n return; // Server-side, do nothing\n }\n\n const title = options?.title || 'Download OneTapForms for Faster Form Completion';\n const message = options?.message ||\n 'Complete forms in seconds with one tap! Download the OneTapForms app to instantly fill forms using Face ID/Touch ID.';\n const buttonText = options?.buttonText || 'Download App';\n const appUrl = this.getAppDownloadUrl();\n\n // Create a simple modal/prompt\n const modal = document.createElement('div');\n modal.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n `;\n\n const content = document.createElement('div');\n content.style.cssText = `\n background: white;\n padding: 24px;\n border-radius: 12px;\n max-width: 400px;\n margin: 20px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n `;\n\n const titleEl = document.createElement('h3');\n titleEl.textContent = title;\n titleEl.style.cssText = `\n margin: 0 0 12px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n `;\n\n const messageEl = document.createElement('p');\n messageEl.textContent = message;\n messageEl.style.cssText = `\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #666;\n line-height: 1.5;\n `;\n\n const buttonContainer = document.createElement('div');\n buttonContainer.style.cssText = `\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n `;\n\n const dismissBtn = document.createElement('button');\n dismissBtn.textContent = 'Maybe Later';\n dismissBtn.style.cssText = `\n padding: 10px 20px;\n border: 1px solid #ddd;\n background: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n color: #666;\n `;\n dismissBtn.onclick = () => {\n document.body.removeChild(modal);\n if (options?.onDismiss) {\n options.onDismiss();\n }\n };\n\n const downloadBtn = document.createElement('button');\n downloadBtn.textContent = buttonText;\n downloadBtn.style.cssText = `\n padding: 10px 20px;\n border: none;\n background: #007AFF;\n color: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n `;\n downloadBtn.onclick = () => {\n window.open(appUrl, '_blank');\n document.body.removeChild(modal);\n };\n\n buttonContainer.appendChild(dismissBtn);\n buttonContainer.appendChild(downloadBtn);\n\n content.appendChild(titleEl);\n content.appendChild(messageEl);\n content.appendChild(buttonContainer);\n modal.appendChild(content);\n\n // Close on background click\n modal.onclick = (e) => {\n if (e.target === modal) {\n document.body.removeChild(modal);\n if (options?.onDismiss) {\n options.onDismiss();\n }\n }\n };\n\n document.body.appendChild(modal);\n }\n}\n\nexport default OneTapForms;\n","import type { AutofillPreviewOptions, AutofillPreviewResult } from './types';\n\n/**\n * Helper to attach the canonical mapping attribute to a DOM element.\n */\nexport function otfFieldAttr(canonicalName: string): Record<string, string> {\n return { 'data-otf-field': canonicalName };\n}\n\n/**\n * Collects all elements with a data-otf-field attribute.\n * Returns the canonical name and the element reference.\n */\nexport function collectMappedFields(root: ParentNode = document): Array<{ name: string; element: Element }> {\n if (typeof document === 'undefined') return [];\n const nodes = Array.from(root.querySelectorAll('[data-otf-field]'));\n return nodes\n .map((el) => {\n const name = el.getAttribute('data-otf-field');\n return name ? { name, element: el } : null;\n })\n .filter((item): item is { name: string; element: Element } => Boolean(item));\n}\n\n/**\n * Preview autofill values from the backend without mutating the DOM.\n * The caller is responsible for applying values to inputs after user consent.\n */\nexport async function previewAutofill(options: AutofillPreviewOptions): Promise<AutofillPreviewResult> {\n const apiUrl = options.apiUrl || 'https://api.createlex.com/api/onetapforms/autofill/preview';\n const payload = {\n fields: options.fields || null,\n formTemplate: options.formTemplate,\n };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (options.token) {\n headers['Authorization'] = `Bearer ${options.token}`;\n }\n if (options.userId) {\n headers['x-user-id'] = options.userId;\n }\n\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Autofill preview failed: ${response.status} ${text}`);\n }\n\n return response.json();\n}\n","// Export the OneTapForms class and types\nexport { OneTapForms, default } from './sdk';\nexport type {\n OneTapFormsConfig,\n RequestOptions,\n CompletionResult,\n AutofillPreviewOptions,\n AutofillPreviewResult,\n} from './types';\nexport { otfFieldAttr, collectMappedFields, previewAutofill } from './autofill';\n\n// Widget auto-initialization for CDN/script tag usage\n// This runs automatically when loaded via <script> tag\n\n/**\n * Built-in QR Modal styles (CSS-in-JS, no external CSS required)\n */\nconst MODAL_STYLES = `\n .onetapforms-modal {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n .onetapforms-modal.active {\n opacity: 1;\n }\n .onetapforms-modal-content {\n background: white;\n padding: 32px;\n border-radius: 16px;\n max-width: 360px;\n width: 90%;\n text-align: center;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n transform: scale(0.95);\n transition: transform 0.2s ease;\n }\n .onetapforms-modal.active .onetapforms-modal-content {\n transform: scale(1);\n }\n .onetapforms-modal-title {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n }\n .onetapforms-modal-subtitle {\n margin: 0 0 24px 0;\n font-size: 14px;\n color: #666;\n }\n .onetapforms-qr-container {\n background: #f5f5f5;\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 20px;\n }\n .onetapforms-qr-container img {\n max-width: 100%;\n height: auto;\n }\n .onetapforms-status {\n font-size: 13px;\n color: #888;\n margin-bottom: 16px;\n }\n .onetapforms-close-btn {\n background: #f0f0f0;\n border: none;\n padding: 10px 24px;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: #333;\n transition: background 0.15s;\n }\n .onetapforms-close-btn:hover {\n background: #e0e0e0;\n }\n .onetapforms-spinner {\n width: 200px;\n height: 200px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .onetapforms-spinner::after {\n content: '';\n width: 40px;\n height: 40px;\n border: 3px solid #e0e0e0;\n border-top-color: #007AFF;\n border-radius: 50%;\n animation: onetapforms-spin 0.8s linear infinite;\n }\n @keyframes onetapforms-spin {\n to { transform: rotate(360deg); }\n }\n`;\n\n/**\n * Inject modal styles into the page (once)\n */\nfunction injectStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.getElementById('onetapforms-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'onetapforms-styles';\n style.textContent = MODAL_STYLES;\n document.head.appendChild(style);\n}\n\n/**\n * Create and show a QR modal\n */\nfunction showQRModal(options: {\n title?: string;\n subtitle?: string;\n onClose?: () => void;\n}): {\n setQR: (qrDataUrl: string) => void;\n setStatus: (status: string) => void;\n close: () => void;\n} {\n injectStyles();\n\n const modal = document.createElement('div');\n modal.className = 'onetapforms-modal';\n modal.innerHTML = `\n <div class=\"onetapforms-modal-content\">\n <h3 class=\"onetapforms-modal-title\">${options.title || 'Scan to Complete'}</h3>\n <p class=\"onetapforms-modal-subtitle\">${options.subtitle || 'Scan with your OneTapForms app'}</p>\n <div class=\"onetapforms-qr-container\">\n <div class=\"onetapforms-spinner\"></div>\n </div>\n <p class=\"onetapforms-status\">Waiting for scan...</p>\n <button class=\"onetapforms-close-btn\">Cancel</button>\n </div>\n `;\n\n const qrContainer = modal.querySelector('.onetapforms-qr-container')!;\n const statusEl = modal.querySelector('.onetapforms-status')!;\n const closeBtn = modal.querySelector('.onetapforms-close-btn')!;\n\n const close = () => {\n modal.classList.remove('active');\n setTimeout(() => modal.remove(), 200);\n if (options.onClose) options.onClose();\n };\n\n closeBtn.addEventListener('click', close);\n modal.addEventListener('click', (e) => {\n if (e.target === modal) close();\n });\n\n document.body.appendChild(modal);\n // Trigger animation\n requestAnimationFrame(() => modal.classList.add('active'));\n\n return {\n setQR: (qrDataUrl: string) => {\n qrContainer.innerHTML = `<img src=\"${qrDataUrl}\" alt=\"QR Code\" />`;\n },\n setStatus: (status: string) => {\n statusEl.textContent = status;\n },\n close\n };\n}\n\n/**\n * Initialize widget elements with data-onetapforms attribute\n */\nfunction initWidgets(): void {\n if (typeof document === 'undefined') return;\n\n const widgets = document.querySelectorAll<HTMLElement>('[data-onetapforms]');\n\n widgets.forEach((element) => {\n // Skip if already initialized\n if (element.dataset.onetapformsInit === 'true') return;\n element.dataset.onetapformsInit = 'true';\n\n const clientId = element.dataset.clientId;\n const clientSecret = element.dataset.clientSecret;\n const purpose = element.dataset.purpose || 'Complete form';\n const bundles = element.dataset.bundles?.split(',').map(b => b.trim()) || ['basic'];\n const formId = element.dataset.formId;\n const apiUrl = element.dataset.apiUrl;\n\n if (!clientId) {\n console.error('[OneTapForms] Missing data-client-id attribute');\n return;\n }\n\n // Import OneTapForms dynamically to avoid circular deps\n import('./sdk').then(({ OneTapForms }) => {\n const sdk = new OneTapForms({\n clientId,\n clientSecret,\n apiUrl\n });\n\n element.addEventListener('click', async (e) => {\n e.preventDefault();\n\n let modal: ReturnType<typeof showQRModal> | null = null;\n\n try {\n await sdk.request({\n purpose,\n bundles,\n onQRReady: (qrDataUrl) => {\n modal = showQRModal({\n title: 'Scan with OneTapForms',\n subtitle: purpose,\n onClose: () => sdk.cancelPolling()\n });\n modal.setQR(qrDataUrl);\n },\n onComplete: (result) => {\n if (modal) {\n modal.setStatus('Complete!');\n setTimeout(() => modal?.close(), 500);\n }\n\n // Dispatch custom event with result\n const event = new CustomEvent('onetapforms:complete', {\n bubbles: true,\n detail: result\n });\n element.dispatchEvent(event);\n\n // Auto-inject token into form if formId is specified\n if (formId) {\n const form = document.getElementById(formId) as HTMLFormElement;\n if (form) {\n let tokenInput = form.querySelector('input[name=\"onetapforms_token\"]') as HTMLInputElement;\n if (!tokenInput) {\n tokenInput = document.createElement('input');\n tokenInput.type = 'hidden';\n tokenInput.name = 'onetapforms_token';\n form.appendChild(tokenInput);\n }\n tokenInput.value = result.token;\n }\n }\n },\n onError: (error) => {\n if (modal) modal.close();\n\n const event = new CustomEvent('onetapforms:error', {\n bubbles: true,\n detail: { error }\n });\n element.dispatchEvent(event);\n }\n });\n } catch (error) {\n console.error('[OneTapForms] Request failed:', error);\n\n const event = new CustomEvent('onetapforms:error', {\n bubbles: true,\n detail: { error }\n });\n element.dispatchEvent(event);\n }\n });\n });\n });\n}\n\n// Auto-initialize on DOM ready (for UMD/script tag usage)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initWidgets);\n } else {\n // DOM already ready\n initWidgets();\n }\n\n // Also observe for dynamically added elements\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.addedNodes.length) {\n initWidgets();\n }\n }\n });\n\n if (document.body) {\n observer.observe(document.body, { childList: true, subtree: true });\n } else {\n document.addEventListener('DOMContentLoaded', () => {\n observer.observe(document.body, { childList: true, subtree: true });\n });\n }\n}\n\n// Export widget utilities for advanced usage\nexport { initWidgets, showQRModal };\n"],"names":["OneTapFormsImpl"],"mappings":"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"}
@@ -2405,6 +2405,58 @@
2405
2405
  default: OneTapForms
2406
2406
  });
2407
2407
 
2408
+ /**
2409
+ * Helper to attach the canonical mapping attribute to a DOM element.
2410
+ */
2411
+ function otfFieldAttr(canonicalName) {
2412
+ return { 'data-otf-field': canonicalName };
2413
+ }
2414
+ /**
2415
+ * Collects all elements with a data-otf-field attribute.
2416
+ * Returns the canonical name and the element reference.
2417
+ */
2418
+ function collectMappedFields(root = document) {
2419
+ if (typeof document === 'undefined')
2420
+ return [];
2421
+ const nodes = Array.from(root.querySelectorAll('[data-otf-field]'));
2422
+ return nodes
2423
+ .map((el) => {
2424
+ const name = el.getAttribute('data-otf-field');
2425
+ return name ? { name, element: el } : null;
2426
+ })
2427
+ .filter((item) => Boolean(item));
2428
+ }
2429
+ /**
2430
+ * Preview autofill values from the backend without mutating the DOM.
2431
+ * The caller is responsible for applying values to inputs after user consent.
2432
+ */
2433
+ async function previewAutofill(options) {
2434
+ const apiUrl = options.apiUrl || 'https://api.createlex.com/api/onetapforms/autofill/preview';
2435
+ const payload = {
2436
+ fields: options.fields || null,
2437
+ formTemplate: options.formTemplate,
2438
+ };
2439
+ const headers = {
2440
+ 'Content-Type': 'application/json',
2441
+ };
2442
+ if (options.token) {
2443
+ headers['Authorization'] = `Bearer ${options.token}`;
2444
+ }
2445
+ if (options.userId) {
2446
+ headers['x-user-id'] = options.userId;
2447
+ }
2448
+ const response = await fetch(apiUrl, {
2449
+ method: 'POST',
2450
+ headers,
2451
+ body: JSON.stringify(payload),
2452
+ });
2453
+ if (!response.ok) {
2454
+ const text = await response.text();
2455
+ throw new Error(`Autofill preview failed: ${response.status} ${text}`);
2456
+ }
2457
+ return response.json();
2458
+ }
2459
+
2408
2460
  // Export the OneTapForms class and types
2409
2461
  // Widget auto-initialization for CDN/script tag usage
2410
2462
  // This runs automatically when loaded via <script> tag
@@ -2682,8 +2734,11 @@
2682
2734
  }
2683
2735
 
2684
2736
  exports.OneTapForms = OneTapForms;
2737
+ exports.collectMappedFields = collectMappedFields;
2685
2738
  exports.default = OneTapForms;
2686
2739
  exports.initWidgets = initWidgets;
2740
+ exports.otfFieldAttr = otfFieldAttr;
2741
+ exports.previewAutofill = previewAutofill;
2687
2742
  exports.showQRModal = showQRModal;
2688
2743
 
2689
2744
  Object.defineProperty(exports, '__esModule', { value: true });