domma-cms 0.14.6 → 0.14.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.14.6",
3
+ "version": "0.14.8",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -1 +1 @@
1
- (function(c,l){typeof module<"u"&&module.exports?module.exports=l():c.FormLogicEngine=l()})(typeof globalThis<"u"?globalThis:this,function(){"use strict";function c(e){return e===""||e===null||e===void 0?"":String(e)}function l(e){const s=parseFloat(e);return isNaN(s)?null:s}function f(e){return e==null?!0:typeof e=="string"?e.trim()==="":Array.isArray(e)?e.length===0:!1}function p(e,s){if(!e||!e.field||!e.operator)return!0;const t=s[e.field],n=c(t),i=c(e.value);switch(e.operator){case"equals":return n===i;case"not_equals":return n!==i;case"contains":return n.toLowerCase().includes(i.toLowerCase());case"not_contains":return!n.toLowerCase().includes(i.toLowerCase());case"starts_with":return n.toLowerCase().startsWith(i.toLowerCase());case"ends_with":return n.toLowerCase().endsWith(i.toLowerCase());case"greater_than":{const r=l(t),a=l(e.value);return r!==null&&a!==null&&r>a}case"less_than":{const r=l(t),a=l(e.value);return r!==null&&a!==null&&r<a}case"is_empty":return f(t);case"is_not_empty":return!f(t);case"in":return(Array.isArray(e.value)?e.value.map(c):String(e.value).split(",").map(a=>a.trim())).includes(n);case"not_in":return!(Array.isArray(e.value)?e.value.map(c):String(e.value).split(",").map(a=>a.trim())).includes(n);case"matches_regex":try{const r=e.flags||"";return new RegExp(e.value,r).test(n)}catch{return!1}default:return!0}}function u(e,s){return e?Array.isArray(e.all)?e.all.every(t=>t.all||t.any?u(t,s):p(t,s)):Array.isArray(e.any)?e.any.some(t=>t.all||t.any?u(t,s):p(t,s)):e.field&&e.operator?p(e,s):!0:!0}function y(e,s){const t=e.logic;if(!t||!t.visibility)return"visible";const n=t.visibility,i=n.conditions||[];for(const r of i)if(r.when&&u(r.when,s))return r.then==="hidden"?"hidden":"visible";return n.default==="hidden"?"hidden":"visible"}function d(e,s){const t=e.logic;if(!t||!t.requirement)return e.required||!1;const n=t.requirement,i=n.conditions||[];for(const r of i)if(r.when&&u(r.when,s))return r.then===!0;return n.default===!0}function h(e,s,t){const n=e.logic;if(!n||!Array.isArray(n.validation))return[];const i=[];for(const r of n.validation)switch(r.type){case"regex":{if(!f(s))try{new RegExp(r.pattern||"",r.flags||"").test(c(s))||i.push({message:r.message||"Invalid format."})}catch{}break}case"match":{const a=t[r.field];!f(s)&&c(s)!==c(a)&&i.push({message:r.message||"Fields do not match."});break}}return i}function m(e,s){const t=e.logic;if(!t||!t.cascade||!t.cascade.sourceField)return null;const n=t.cascade,i=c(s[n.sourceField]),r=n.mapping||{};return Object.prototype.hasOwnProperty.call(r,i)?r[i]||[]:n.defaultOptions||null}function _(e,s){s==="fade"?(e.style.transition="opacity 0.25s ease",e.style.opacity="1",requestAnimationFrame(function(){e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.opacity=""},260)})):s==="slide"?(e.style.overflow="hidden",e.style.maxHeight=e.scrollHeight+"px",e.style.transition="max-height 0.3s ease, opacity 0.2s ease",requestAnimationFrame(function(){e.style.maxHeight="0",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},320)})):s==="scale"&&(e.style.transition="opacity 0.2s ease, transform 0.2s ease",e.style.transform="scale(1)",e.style.opacity="1",requestAnimationFrame(function(){e.style.transform="scale(0.95)",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.transform="",e.style.opacity=""},220)}))}function v(e,s){e.classList.remove("fb-field-hidden"),s==="fade"?(e.style.opacity="0",e.style.transition="opacity 0.25s ease",requestAnimationFrame(function(){e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.opacity=""},260)})):s==="slide"?(e.style.overflow="hidden",e.style.maxHeight="0",e.style.opacity="0",e.style.transition="max-height 0.3s ease, opacity 0.2s ease",requestAnimationFrame(function(){e.style.maxHeight=e.scrollHeight+"px",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},320)})):s==="scale"&&(e.style.transform="scale(0.95)",e.style.opacity="0",e.style.transition="opacity 0.2s ease, transform 0.2s ease",requestAnimationFrame(function(){e.style.transform="scale(1)",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.transform="",e.style.opacity=""},220)}))}function o(e,s){this._form=e,this._wrapper=s,this._fields=(e.fields||[]).filter(t=>t.type!=="page-break"),this._listeners=[],this._depMap=new Map,this._initialEval=!1}return o.prototype._buildDepMap=function(){this._depMap.clear();const e=this;e._fields.forEach(function(s){const t=s.logic;if(!t)return;function n(i){if(!i)return;(i.all||i.any||[]).forEach(function(a){a.field?(e._depMap.has(a.field)||e._depMap.set(a.field,new Set),e._depMap.get(a.field).add(s.name)):n(a)})}if(t.visibility&&(t.visibility.conditions||[]).forEach(function(i){n(i.when)}),t.requirement&&(t.requirement.conditions||[]).forEach(function(i){n(i.when)}),t.cascade&&t.cascade.sourceField){const i=t.cascade.sourceField;e._depMap.has(i)||e._depMap.set(i,new Set),e._depMap.get(i).add(s.name)}})},o.prototype._getValues=function(){const e={};return this._fields.forEach(function(s){const t=this._wrapper.querySelector('[name="'+s.name+'"]');if(t)if(t.type==="radio"){const n=this._wrapper.querySelector('[name="'+s.name+'"]:checked');e[s.name]=n?n.value:""}else t.type==="checkbox"?e[s.name]=t.checked?t.value||"true":"":e[s.name]=t.value},this),e},o.prototype._applyVisibility=function(e,s){const n=y(e,s)==="hidden",i=this._findFieldWrapper(e.name);if(!i)return;i.setAttribute("aria-hidden",String(n));const r=this._initialEval?"none":e.logic?.visibility?.transition||"none";if(r==="none"){i.classList.toggle("fb-field-hidden",n);return}i.style.transition="",n?_(i,r):v(i,r)},o.prototype._applyRequirement=function(e,s){const t=d(e,s),n=this._wrapper.querySelector('[name="'+e.name+'"]');n&&(t?n.setAttribute("required",""):n.removeAttribute("required"))},o.prototype._applyCascade=function(e,s){const t=m(e,s);if(t===null)return;const n=this._wrapper.querySelector('select[name="'+e.name+'"]');if(!n)return;const i=n.value;n.textContent="",t.forEach(function(r){const a=document.createElement("option");a.value=r.value,a.textContent=r.label||r.value,r.value===i&&(a.selected=!0),n.appendChild(a)})},o.prototype._applyValidation=function(e,s){const t=this._wrapper.querySelector('[name="'+e.name+'"]');if(!t)return;const n=t.type==="checkbox"?t.checked?t.value||"true":"":t.value,i=h(e,n,s);let r=t.parentNode.querySelector(".fb-validation-error");i.length?(r||(r=document.createElement("div"),r.className="fb-validation-error",t.parentNode.appendChild(r)),r.textContent=i[0].message):r&&r.remove()},o.prototype._findFieldWrapper=function(e){const s=this._wrapper.querySelector('[name="'+e+'"]');if(!s)return null;const t=s.closest("form")||this._wrapper;let n=s;for(;n.parentNode&&n.parentNode!==t;)n=n.parentNode;return n},o.prototype.evaluate=function(e){const s=this._getValues(),t=this;let n;if(e&&this._depMap.has(e)){const i=this._depMap.get(e);n=this._fields.filter(function(r){return i.has(r.name)})}else n=this._fields;n.forEach(function(i){i.logic&&(t._applyVisibility(i,s),t._applyRequirement(i,s),t._applyCascade(i,s))})},o.prototype.init=function(){this._buildDepMap();const e=this;this._wrapper.querySelectorAll("input, select, textarea").forEach(function(t){const n=t.getAttribute("name");if(!n)return;const i=function(){e.evaluate(n)};t.addEventListener("input",i),t.addEventListener("change",i),e._listeners.push({el:t,event:"input",fn:i}),e._listeners.push({el:t,event:"change",fn:i});const r=e._fields.find(function(a){return a.name===n});if(r&&r.logic&&Array.isArray(r.logic.validation)&&r.logic.validation.length){const a=function(){const g=e._getValues();e._applyValidation(r,g)};t.addEventListener("blur",a),e._listeners.push({el:t,event:"blur",fn:a})}}),this._initialEval=!0,this.evaluate(),this._initialEval=!1},o.prototype.destroy=function(){this._listeners.forEach(function(e){e.el.removeEventListener(e.event,e.fn)}),this._listeners=[]},{evaluateCondition:p,evaluateConditionGroup:u,evaluateFieldVisibility:y,evaluateFieldRequirement:d,validateField:h,getCascadeOptions:m,FormLogicRuntime:o}});
1
+ (function(c,l){typeof module<"u"&&module.exports?module.exports=l():c.FormLogicEngine=l()})(typeof globalThis<"u"?globalThis:this,function(){"use strict";function c(e){return e===""||e===null||e===void 0?"":String(e)}function l(e){const s=parseFloat(e);return isNaN(s)?null:s}function f(e){return e==null?!0:typeof e=="string"?e.trim()==="":Array.isArray(e)?e.length===0:!1}function p(e,s){if(!e||!e.field||!e.operator)return!0;const t=s[e.field],n=c(t),r=c(e.value);switch(e.operator){case"equals":return n===r;case"not_equals":return n!==r;case"contains":return n.toLowerCase().includes(r.toLowerCase());case"not_contains":return!n.toLowerCase().includes(r.toLowerCase());case"starts_with":return n.toLowerCase().startsWith(r.toLowerCase());case"ends_with":return n.toLowerCase().endsWith(r.toLowerCase());case"greater_than":{const i=l(t),a=l(e.value);return i!==null&&a!==null&&i>a}case"less_than":{const i=l(t),a=l(e.value);return i!==null&&a!==null&&i<a}case"is_empty":return f(t);case"is_not_empty":return!f(t);case"in":return(Array.isArray(e.value)?e.value.map(c):String(e.value).split(",").map(a=>a.trim())).includes(n);case"not_in":return!(Array.isArray(e.value)?e.value.map(c):String(e.value).split(",").map(a=>a.trim())).includes(n);case"matches_regex":try{const i=e.flags||"";return new RegExp(e.value,i).test(n)}catch(i){return typeof console<"u"&&console.warn&&console.warn('[FormLogicEngine] Invalid regex in condition for field "'+e.field+'": '+e.value,i&&i.message),!1}default:return!0}}function u(e,s){return e?Array.isArray(e.all)?e.all.every(t=>t.all||t.any?u(t,s):p(t,s)):Array.isArray(e.any)?e.any.some(t=>t.all||t.any?u(t,s):p(t,s)):e.field&&e.operator?p(e,s):!0:!0}function d(e,s){const t=e.logic;if(!t||!t.visibility)return"visible";const n=t.visibility,r=n.conditions||[];for(const i of r)if(i.when&&u(i.when,s))return i.then==="hidden"?"hidden":"visible";return n.default==="hidden"?"hidden":"visible"}function y(e,s){const t=e.logic;if(!t||!t.requirement)return e.required||!1;const n=t.requirement,r=n.conditions||[];for(const i of r)if(i.when&&u(i.when,s))return i.then===!0;return n.default===!0}function h(e,s,t){const n=e.logic;if(!n||!Array.isArray(n.validation))return[];const r=[];for(const i of n.validation)switch(i.type){case"regex":{if(!f(s))try{new RegExp(i.pattern||"",i.flags||"").test(c(s))||r.push({message:i.message||"Invalid format."})}catch{}break}case"match":{const a=t[i.field];!f(s)&&c(s)!==c(a)&&r.push({message:i.message||"Fields do not match."});break}}return r}function m(e,s){const t=e.logic;if(!t||!t.cascade||!t.cascade.sourceField)return null;const n=t.cascade,r=c(s[n.sourceField]),i=n.mapping||{};return Object.prototype.hasOwnProperty.call(i,r)?i[r]||[]:n.defaultOptions||null}function _(e,s){s==="fade"?(e.style.transition="opacity 0.25s ease",e.style.opacity="1",requestAnimationFrame(function(){e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.opacity=""},260)})):s==="slide"?(e.style.overflow="hidden",e.style.maxHeight=e.scrollHeight+"px",e.style.transition="max-height 0.3s ease, opacity 0.2s ease",requestAnimationFrame(function(){e.style.maxHeight="0",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},320)})):s==="scale"&&(e.style.transition="opacity 0.2s ease, transform 0.2s ease",e.style.transform="scale(1)",e.style.opacity="1",requestAnimationFrame(function(){e.style.transform="scale(0.95)",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.transform="",e.style.opacity=""},220)}))}function v(e,s){e.classList.remove("fb-field-hidden"),s==="fade"?(e.style.opacity="0",e.style.transition="opacity 0.25s ease",requestAnimationFrame(function(){e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.opacity=""},260)})):s==="slide"?(e.style.overflow="hidden",e.style.maxHeight="0",e.style.opacity="0",e.style.transition="max-height 0.3s ease, opacity 0.2s ease",requestAnimationFrame(function(){e.style.maxHeight=e.scrollHeight+"px",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},320)})):s==="scale"&&(e.style.transform="scale(0.95)",e.style.opacity="0",e.style.transition="opacity 0.2s ease, transform 0.2s ease",requestAnimationFrame(function(){e.style.transform="scale(1)",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.transform="",e.style.opacity=""},220)}))}function o(e,s){this._form=e,this._wrapper=s,this._fields=(e.fields||[]).filter(t=>t.type!=="page-break"),this._listeners=[],this._depMap=new Map,this._initialEval=!1}return o.prototype._buildDepMap=function(){this._depMap.clear();const e=this;e._fields.forEach(function(s){const t=s.logic;if(!t)return;function n(r){if(!r)return;(r.all||r.any||[]).forEach(function(a){a.field?(e._depMap.has(a.field)||e._depMap.set(a.field,new Set),e._depMap.get(a.field).add(s.name)):n(a)})}if(t.visibility&&(t.visibility.conditions||[]).forEach(function(r){n(r.when)}),t.requirement&&(t.requirement.conditions||[]).forEach(function(r){n(r.when)}),t.cascade&&t.cascade.sourceField){const r=t.cascade.sourceField;e._depMap.has(r)||e._depMap.set(r,new Set),e._depMap.get(r).add(s.name)}})},o.prototype._getValues=function(){const e={};return this._fields.forEach(function(s){const t=this._wrapper.querySelector('[name="'+s.name+'"]');if(t)if(t.type==="radio"){const n=this._wrapper.querySelector('[name="'+s.name+'"]:checked');e[s.name]=n?n.value:""}else if(t.type==="checkbox"){const n=this._wrapper.querySelectorAll('input[type="checkbox"][name="'+s.name+'"]');if(n.length>1){const r=[];n.forEach(function(i){i.checked&&r.push(i.value)}),e[s.name]=r}else e[s.name]=t.checked?t.value||"true":""}else e[s.name]=t.value},this),e},o.prototype._applyVisibility=function(e,s){const n=d(e,s)==="hidden",r=this._findFieldWrapper(e.name);if(!r)return;r.setAttribute("aria-hidden",String(n));const i=this._initialEval?"none":e.logic?.visibility?.transition||"none";if(i==="none"){r.classList.toggle("fb-field-hidden",n);return}r.style.transition="",n?_(r,i):v(r,i)},o.prototype._applyRequirement=function(e,s){const t=y(e,s),n=this._wrapper.querySelector('[name="'+e.name+'"]');n&&(t?n.setAttribute("required",""):n.removeAttribute("required"))},o.prototype._applyCascade=function(e,s){const t=m(e,s);if(t===null)return;const n=this._wrapper.querySelector('select[name="'+e.name+'"]');if(!n)return;const r=n.value;n.textContent="",t.forEach(function(i){const a=document.createElement("option");a.value=i.value,a.textContent=i.label||i.value,i.value===r&&(a.selected=!0),n.appendChild(a)})},o.prototype._applyValidation=function(e,s){const t=this._wrapper.querySelector('[name="'+e.name+'"]');if(!t)return;const n=t.type==="checkbox"?t.checked?t.value||"true":"":t.value,r=h(e,n,s);let i=t.parentNode.querySelector(".fb-validation-error");r.length?(i||(i=document.createElement("div"),i.className="fb-validation-error",t.parentNode.appendChild(i)),i.textContent=r[0].message):i&&i.remove()},o.prototype._findFieldWrapper=function(e){const s=this._wrapper.querySelector('[name="'+e+'"]');if(!s)return null;const t=s.closest("form")||this._wrapper;let n=s;for(;n.parentNode&&n.parentNode!==t;)n=n.parentNode;return n},o.prototype.evaluate=function(e){const s=this._getValues(),t=this;let n;if(e&&this._depMap.has(e)){const r=this._depMap.get(e);n=this._fields.filter(function(i){return r.has(i.name)})}else n=this._fields;n.forEach(function(r){r.logic&&(t._applyVisibility(r,s),t._applyRequirement(r,s),t._applyCascade(r,s))})},o.prototype.init=function(){this._buildDepMap();const e=this;this._wrapper.querySelectorAll("input, select, textarea").forEach(function(t){const n=t.getAttribute("name");if(!n)return;const r=function(){e.evaluate(n)};t.addEventListener("input",r),t.addEventListener("change",r),e._listeners.push({el:t,event:"input",fn:r}),e._listeners.push({el:t,event:"change",fn:r});const i=e._fields.find(function(a){return a.name===n});if(i&&i.logic&&Array.isArray(i.logic.validation)&&i.logic.validation.length){const a=function(){const g=e._getValues();e._applyValidation(i,g)};t.addEventListener("blur",a),e._listeners.push({el:t,event:"blur",fn:a})}}),this._initialEval=!0,this.evaluate(),this._initialEval=!1},o.prototype.destroy=function(){this._listeners.forEach(function(e){e.el.removeEventListener(e.event,e.fn)}),this._listeners=[]},{evaluateCondition:p,evaluateConditionGroup:u,evaluateFieldVisibility:d,evaluateFieldRequirement:y,validateField:h,getCascadeOptions:m,FormLogicRuntime:o}});
@@ -1 +1 @@
1
- const targets=document.querySelectorAll("[data-form]");targets.length&&targets.forEach(initFormTarget);function showMessage(i,r,t){const e=i.querySelector(".fb-form-success, .fb-form-error");e&&e.remove();const s=document.createElement("div");s.className=t==="success"?"fb-form-success":"fb-form-error",s.textContent=r,i.appendChild(s)}function buildBlueprintFromFields(i,r){const t={};return i.forEach(function(e){if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const s=e.type==="checkbox"?"boolean":e.type==="date"?"string":e.type,o={...e.formConfig||{}};o.span==="full"&&r&&(o.span=r),t[e.name]={type:s,label:e.label||e.name,required:e.required||!1,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...o}},e.minLength!==void 0&&(t[e.name].minLength=e.minLength),e.maxLength!==void 0&&(t[e.name].maxLength=e.maxLength),e.min!==void 0&&(t[e.name].min=e.min),e.max!==void 0&&(t[e.name].max=e.max)}),t}function buildInitialData(i){const r={};return i.forEach(function(t){if(!(!t.name||t.type==="page-break"||t.type==="spacer")&&(t.type==="select"||t.type==="multiselect")&&t.required){const e=(t.options||[])[0];e&&(r[t.name]=typeof e=="object"?e.value:e)}}),r}function patchDateInputs(i,r){(r||[]).forEach(function(t){if(t.type!=="date"||!t.name)return;const e=i.querySelector('[name="'+t.name+'"]');e&&e.type!=="date"&&(e.type="date")})}function buildWizardSteps(i,r){const t=[];let e=[],s=r||"Step 1",o="";return i.forEach(function(m){m.type==="page-break"?(t.push({title:s,description:o,fieldGroup:e}),e=[],s=m.label||"Step "+(t.length+1),o=m.description||""):m.type!=="spacer"&&e.push(m)}),t.push({title:s,description:o,fieldGroup:e}),t}function injectHoneypot(i){const r=document.createElement("div");r.className="fb-form-honeypot",r.setAttribute("aria-hidden","true");const t=document.createElement("input");t.name="website",t.type="text",t.tabIndex=-1,t.autocomplete="url",t.placeholder="https://",r.appendChild(t);const e=document.createElement("input");e.name="_t",e.type="hidden",e.value=Date.now(),r.appendChild(e),i.appendChild(r)}function injectSpacers(i,r){const t=i.querySelector("form");if(!t)return;const e=Array.from(t.querySelectorAll(".form-group"));let s=0;r.forEach(function(o){if(o.type==="spacer"){const m=document.createElement("div");m.className="fb-spacer";const a=e[s];if(a)t.insertBefore(m,a);else{const u=t.querySelector('[type="submit"]');u?t.insertBefore(m,u):t.appendChild(m)}}else o.type!=="page-break"&&s++})}function submitForm(i,r,t,e,s){const o=s||e,m=o.querySelector('[name="website"]')?.value||"",a=o.querySelector('[name="_t"]')?.value||"",u=Object.assign({},r,{_hp:m,_t:a});return fetch("/api/forms/submit/"+i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)}).then(c=>c.json().then(n=>({ok:c.ok,body:n}))).then(c=>{c.ok&&c.body.ok?(e.textContent="",showMessage(e,c.body.message||t.successMessage||"Thank you.","success")):showMessage(e,c.body.error||"Something went wrong.","error")}).catch(()=>{showMessage(e,"Unable to submit. Please check your connection.","error")})}function renderManualForm(i,r,t,e,s){const o=document.createElement("form");o.noValidate=!0,r.forEach(function(a){const u=document.createElement("div");u.className="form-group",u.style.marginBottom="1.25rem";const c=document.createElement("label");if(c.className="form-label",c.textContent=a.label||a.name,a.required){const p=document.createElement("span");p.textContent=" *",p.style.color="#f87171",c.appendChild(p)}let n;a.type==="textarea"?(n=document.createElement("textarea"),n.rows=a.formConfig?.rows||4,n.className="form-input"):a.type==="select"?(n=document.createElement("select"),n.className="form-input",(a.options||[]).forEach(function(p){const l=document.createElement("option");l.value=typeof p=="string"?p:p.value??"",l.textContent=typeof p=="string"?p:p.label||l.value,n.appendChild(l)})):(n=document.createElement("input"),n.type=a.type||"text",n.className="form-input",a.placeholder&&(n.placeholder=a.placeholder)),n.name=a.name,n.required=a.required||!1,u.appendChild(c),u.appendChild(n),o.appendChild(u)}),t.honeypot&&injectHoneypot(o);const m=document.createElement("button");m.type="submit",m.className="btn btn-primary",m.textContent=t.submitText||"Submit",o.appendChild(m),o.addEventListener("submit",function(a){a.preventDefault();const u={};if(r.forEach(function(c){const n=o.querySelector('[name="'+c.name+'"]');n&&(u[c.name]=n.value)}),window.FormLogicEngine&&s){const c=window.FormLogicEngine,n=[],p=[];if(r.forEach(function(l){if(c.evaluateFieldVisibility(l,u)==="hidden"){delete u[l.name];return}const h=c.evaluateFieldRequirement(l,u),f=u[l.name];h&&(!f||!String(f).trim())&&n.push(l.label||l.name);const d=c.validateField(l,f||"",u);d.length&&p.push(d[0].message)}),n.length||p.length){const l=[];n.length&&l.push("Required: "+n.join(", ")),p.length&&l.push(p.join("; ")),showMessage(i,l.join(". "),"error");return}}i.classList.add("fb-form-loading"),m.disabled=!0,submitForm(e,u,t,i,o).finally(function(){i.classList.remove("fb-form-loading"),m.disabled=!1})}),i.appendChild(o),window.FormLogicEngine&&s&&r.some(a=>a.logic)&&new window.FormLogicEngine.FormLogicRuntime(s,i).init()}function initFormTarget(i){const r=i.getAttribute("data-form");r&&fetch("/api/forms/"+r+"/public").then(t=>{if(!t.ok)throw new Error("Form not found: "+r);return t.json()}).then(t=>{const e=t.fields||[],s=t.settings||{},o=document.createElement("div");o.className="fb-form-wrapper",i.appendChild(o);const m=e.some(a=>a.type==="page-break");if(typeof Domma<"u"&&Domma.forms){const a=s.columns||1;if(m&&Domma.forms.wizard){const c=buildWizardSteps(e,t.title).map(function(n){return{title:n.title,description:n.description,fields:buildBlueprintFromFields(n.fieldGroup,a)}});if(Domma.forms.wizard(o,{schema:{steps:c},onSubmit:function(n){return submitForm(r,n,s,o,null)}}),patchDateInputs(o,e),window.FormLogicEngine&&e.some(n=>n.logic)&&new window.FormLogicEngine.FormLogicRuntime(t,o).init(),s.honeypot){const n=o.querySelector("form");n&&injectHoneypot(n)}}else if(Domma.forms.render){const u=buildBlueprintFromFields(e,a),c=buildInitialData(e);if(Domma.forms.render(o,u,c,{submitText:s.submitText||"Submit",layout:s.layout||"stacked",columns:a,onSubmit:function(n){return submitForm(r,n,s,o,null)}}),patchDateInputs(o,e),window.FormLogicEngine&&e.some(n=>n.logic)&&new window.FormLogicEngine.FormLogicRuntime(t,o).init(),e.some(n=>n.type==="spacer")&&injectSpacers(o,e),s.honeypot){const n=o.querySelector("form");n&&injectHoneypot(n)}}}else renderManualForm(o,e.filter(a=>a.type!=="page-break"&&a.type!=="spacer"),s,r,t)}).catch(t=>{const e=document.createElement("p");e.textContent="Form unavailable.",e.style.cssText="color:#f87171;font-style:italic;",i.appendChild(e),console.warn("[forms]",t.message)})}
1
+ const targets=document.querySelectorAll("[data-form]");targets.length&&targets.forEach(initFormTarget);function showMessage(i,r,t){const e=i.querySelector(".fb-form-success, .fb-form-error");e&&e.remove();const a=document.createElement("div");a.className=t==="success"?"fb-form-success":"fb-form-error",a.textContent=r,i.appendChild(a)}function attachRuntimeLifecycle(i,r){if(i._formLogicRuntime=r,!i.parentNode||typeof MutationObserver>"u")return;const t=new MutationObserver(function(e){for(const a of e)for(const n of a.removedNodes)if(n===i||n.nodeType===1&&n.contains&&n.contains(i)){r.destroy(),t.disconnect();return}});t.observe(i.parentNode,{childList:!0,subtree:!1})}function buildBlueprintFromFields(i,r){const t={};return i.forEach(function(e){if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const a=e.type==="checkbox"?"boolean":e.type==="date"?"string":e.type,n={...e.formConfig||{}};n.span==="full"&&r&&(n.span=r),t[e.name]={type:a,label:e.label||e.name,required:e.required||!1,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...n}},e.minLength!==void 0&&(t[e.name].minLength=e.minLength),e.maxLength!==void 0&&(t[e.name].maxLength=e.maxLength),e.min!==void 0&&(t[e.name].min=e.min),e.max!==void 0&&(t[e.name].max=e.max)}),t}function buildInitialData(i){const r={};return i.forEach(function(t){if(!(!t.name||t.type==="page-break"||t.type==="spacer")&&(t.type==="select"||t.type==="multiselect")&&t.required){const e=(t.options||[])[0];e&&(r[t.name]=typeof e=="object"?e.value:e)}}),r}function patchDateInputs(i,r){(r||[]).forEach(function(t){if(t.type!=="date"||!t.name)return;const e=i.querySelector('[name="'+t.name+'"]');e&&e.type!=="date"&&(e.type="date")})}function buildWizardSteps(i,r){const t=[];let e=[],a=r||"Step 1",n="";return i.forEach(function(u){u.type==="page-break"?(t.push({title:a,description:n,fieldGroup:e}),e=[],a=u.label||"Step "+(t.length+1),n=u.description||""):u.type!=="spacer"&&e.push(u)}),t.push({title:a,description:n,fieldGroup:e}),t}function injectHoneypot(i){const r=document.createElement("div");r.className="fb-form-honeypot",r.setAttribute("aria-hidden","true");const t=document.createElement("input");t.name="website",t.type="text",t.tabIndex=-1,t.autocomplete="url",t.placeholder="https://",r.appendChild(t);const e=document.createElement("input");e.name="_t",e.type="hidden",e.value=Date.now(),r.appendChild(e),i.appendChild(r)}function injectSpacers(i,r){const t=i.querySelector("form");if(!t)return;const e=Array.from(t.querySelectorAll(".form-group"));let a=0;r.forEach(function(n){if(n.type==="spacer"){const u=document.createElement("div");u.className="fb-spacer";const s=e[a];if(s)t.insertBefore(u,s);else{const l=t.querySelector('[type="submit"]');l?t.insertBefore(u,l):t.appendChild(u)}}else n.type!=="page-break"&&a++})}function submitForm(i,r,t,e,a){const n=a||e,u=n.querySelector('[name="website"]')?.value||"",s=n.querySelector('[name="_t"]')?.value||"",l=Object.assign({},r,{_hp:u,_t:s});return fetch("/api/forms/submit/"+i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)}).then(m=>m.json().then(c=>({ok:m.ok,body:c}))).then(m=>{m.ok&&m.body.ok?(e.textContent="",showMessage(e,m.body.message||t.successMessage||"Thank you.","success")):showMessage(e,m.body.error||"Something went wrong.","error")}).catch(()=>{showMessage(e,"Unable to submit. Please check your connection.","error")})}function renderManualForm(i,r,t,e,a){const n=document.createElement("form");n.noValidate=!0,r.forEach(function(s){const l=document.createElement("div");l.className="form-group",l.style.marginBottom="1.25rem";const m=document.createElement("label");if(m.className="form-label",m.textContent=s.label||s.name,s.required){const o=document.createElement("span");o.textContent=" *",o.style.color="#f87171",m.appendChild(o)}let c;s.type==="textarea"?(c=document.createElement("textarea"),c.rows=s.formConfig?.rows||4,c.className="form-input"):s.type==="select"?(c=document.createElement("select"),c.className="form-input",(s.options||[]).forEach(function(o){const p=document.createElement("option");p.value=typeof o=="string"?o:o.value??"",p.textContent=typeof o=="string"?o:o.label||p.value,c.appendChild(p)})):(c=document.createElement("input"),c.type=s.type||"text",c.className="form-input",s.placeholder&&(c.placeholder=s.placeholder)),c.name=s.name,c.required=s.required||!1,l.appendChild(m),l.appendChild(c),n.appendChild(l)}),t.honeypot&&injectHoneypot(n);const u=document.createElement("button");u.type="submit",u.className="btn btn-primary",u.textContent=t.submitText||"Submit",n.appendChild(u),n.addEventListener("submit",function(s){s.preventDefault();const l={};if(r.forEach(function(m){const c=n.querySelector('[name="'+m.name+'"]');c&&(l[m.name]=c.value)}),window.FormLogicEngine&&a){const m=window.FormLogicEngine,c=[],o=[];if(r.forEach(function(p){if(m.evaluateFieldVisibility(p,l)==="hidden"){delete l[p.name];return}const h=m.evaluateFieldRequirement(p,l),f=l[p.name];h&&(!f||!String(f).trim())&&c.push(p.label||p.name);const d=m.validateField(p,f||"",l);d.length&&o.push(d[0].message)}),c.length||o.length){const p=[];c.length&&p.push("Required: "+c.join(", ")),o.length&&p.push(o.join("; ")),showMessage(i,p.join(". "),"error");return}}i.classList.add("fb-form-loading"),u.disabled=!0,submitForm(e,l,t,i,n).finally(function(){i.classList.remove("fb-form-loading"),u.disabled=!1})}),i.appendChild(n),window.FormLogicEngine&&a&&r.some(s=>s.logic)&&new window.FormLogicEngine.FormLogicRuntime(a,i).init()}function initFormTarget(i){const r=i.getAttribute("data-form");r&&fetch("/api/forms/"+r+"/public").then(t=>{if(!t.ok)throw new Error("Form not found: "+r);return t.json()}).then(t=>{const e=t.fields||[],a=t.settings||{},n=document.createElement("div");n.className="fb-form-wrapper",i.appendChild(n);const u=e.some(s=>s.type==="page-break");if(typeof Domma<"u"&&Domma.forms){const s=a.columns||1;if(u&&Domma.forms.wizard){const m=buildWizardSteps(e,t.title).map(function(o){return{title:o.title,description:o.description,fields:buildBlueprintFromFields(o.fieldGroup,s)}}),c=Domma.forms.wizard(n,{schema:{steps:m},onSubmit:function(o){return submitForm(r,o,a,n,null)}});Promise.resolve(c).then(function(){if(patchDateInputs(n,e),window.FormLogicEngine&&e.some(o=>o.logic)){const o=new window.FormLogicEngine.FormLogicRuntime(t,n);o.init(),attachRuntimeLifecycle(n,o)}if(a.honeypot){const o=n.querySelector("form");o&&injectHoneypot(o)}})}else if(Domma.forms.render){const l=buildBlueprintFromFields(e,s),m=buildInitialData(e),c=Domma.forms.render(n,l,m,{submitText:a.submitText||"Submit",layout:a.layout||"stacked",columns:s,onSubmit:function(o){return submitForm(r,o,a,n,null)}});Promise.resolve(c).then(function(){if(patchDateInputs(n,e),window.FormLogicEngine&&e.some(o=>o.logic)){const o=new window.FormLogicEngine.FormLogicRuntime(t,n);o.init(),attachRuntimeLifecycle(n,o)}if(e.some(o=>o.type==="spacer")&&injectSpacers(n,e),a.honeypot){const o=n.querySelector("form");o&&injectHoneypot(o)}})}}else renderManualForm(n,e.filter(s=>s.type!=="page-break"&&s.type!=="spacer"),a,r,t)}).catch(t=>{const e=document.createElement("p");e.textContent="Form unavailable.",e.style.cssText="color:#f87171;font-style:italic;",i.appendChild(e),console.warn("[forms]",t.message)})}
@@ -33,7 +33,8 @@ export async function createTransport(smtp) {
33
33
  host: smtp.host,
34
34
  port: smtp.port || 587,
35
35
  secure: smtp.secure || false,
36
- auth: smtp.user ? { user: smtp.user, pass: smtp.pass } : undefined
36
+ auth: smtp.user ? { user: smtp.user, pass: smtp.pass } : undefined,
37
+ tls: { rejectUnauthorized: false }
37
38
  });
38
39
  }
39
40