jails.stdlib 1.1.0 โ†’ 2.0.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.
@@ -0,0 +1,97 @@
1
+ # channel
2
+
3
+ ```ts
4
+ Channel({
5
+ target?: Window | HTMLIFrameElement,
6
+ accept?: string[],
7
+ origin?: string
8
+ })
9
+ ```
10
+
11
+
12
+ # ๐Ÿ“ฌ Channel API Documentation
13
+
14
+ The `channel` utility provides a lightweight, secure interface for sending and receiving messages between windows or iframes using `postMessage`.
15
+
16
+ ---
17
+
18
+ ## โœ… Features
19
+
20
+ * Easy dispatch and subscription to custom message actions.
21
+ * Secure origin validation.
22
+ * Works with iframes or separate window contexts.
23
+
24
+ ---
25
+
26
+ ## ๐Ÿงช Usage
27
+
28
+ ### Parent Page
29
+
30
+ ```ts
31
+ import { Channel } from 'jails.stdlib/channel'
32
+
33
+ const channel = Channel({
34
+ target: document.getElementById('myIframe'), // <iframe id="myIframe" />
35
+ accept: ['*'] // Allowed origins
36
+ })
37
+
38
+ // Send message to iframe
39
+ channel.send('hello', { user: 'Alice' })
40
+
41
+ // Add more listeners later
42
+ channel.on('hi', (data) => {
43
+ console.log('Iframe said hi!', data)
44
+ })
45
+ ```
46
+
47
+ ### Iframe Page
48
+
49
+ ```ts
50
+ const channel = Channel({
51
+ target: window.parent,
52
+ accept: ['*']
53
+ })
54
+ ```
55
+
56
+ ---
57
+
58
+ ## ๐Ÿงน API
59
+
60
+ ### `Channel(options)`
61
+
62
+ Creates a new Channel instance.
63
+
64
+ #### Options:
65
+
66
+ | Option | Type | Description |
67
+ | --------- | ----------------------------- | --------------------------------------- |
68
+ | `target` | `Window \| HTMLIFrameElement` | Target to send messages to |
69
+ | `accept` | `string[]` | Allowed origins (`['*']` to accept all) |
70
+ | `origin` | `string` | The origin used when sending messages, `default`: location.origin |
71
+
72
+ ---
73
+
74
+ ### `.emit(event: string, payload?: any)`
75
+
76
+ Sends a message to the target window.
77
+
78
+ ```ts
79
+ channel.emit('say:hi', { name: 'Bob' })
80
+ ```
81
+
82
+ ---
83
+
84
+ ### `.on(event: string, callback: function )`
85
+
86
+ Listen to an event from the target window.
87
+
88
+ ```ts
89
+ channel.on('logout', () => console.log('Logging out...'))
90
+ ```
91
+
92
+ ---
93
+
94
+ ## ๐Ÿ”’ Security Notes
95
+
96
+ * Always **specify allowed origins** in `accept` to avoid cross-site scripting risks.
97
+ * Avoid using `'*'` unless absolutely necessary (e.g., during development).
@@ -0,0 +1,9 @@
1
+ export declare const Channel: ({ target, accept, origin }: {
2
+ target?: any;
3
+ accept?: any;
4
+ origin?: string;
5
+ }) => {
6
+ on(name: any, callback: any): void;
7
+ emit(event: any, ...payload: any[]): void;
8
+ remove(name: any): void;
9
+ };
@@ -0,0 +1,30 @@
1
+ const a = ({
2
+ target: o = null,
3
+ accept: i = [],
4
+ origin: d = location.origin
5
+ }) => {
6
+ const t = (o == null ? void 0 : o.contentWindow) || o, s = {};
7
+ return window.addEventListener("message", (n) => {
8
+ if (i.includes("*") || i.includes(n.origin)) {
9
+ const { payload: e, event: l } = n.data;
10
+ s[l] && s[l].apply(null, e);
11
+ } else
12
+ throw {
13
+ type: "ACCESS DENIED",
14
+ message: "Cant receive message from: " + n.origin
15
+ };
16
+ }), {
17
+ on(n, e) {
18
+ s[n] = e;
19
+ },
20
+ emit(n, ...e) {
21
+ t.postMessage({ event: n, payload: e }, d);
22
+ },
23
+ remove(n) {
24
+ delete s[n];
25
+ }
26
+ };
27
+ };
28
+ export {
29
+ a as Channel
30
+ };
@@ -0,0 +1,39 @@
1
+
2
+ export const Channel = ({
3
+ target = null as any,
4
+ accept = [] as any,
5
+ origin = location.origin
6
+ }) => {
7
+
8
+ const win = target?.contentWindow || target
9
+ const events = {}
10
+
11
+ window.addEventListener('message', (e) => {
12
+ if( accept.includes('*') || accept.includes(e.origin) ) {
13
+ const { payload, event } = e.data
14
+ if( events[event] ) {
15
+ events[event].apply(null, payload)
16
+ }
17
+ } else {
18
+ throw {
19
+ type : 'ACCESS DENIED',
20
+ message : 'Cant receive message from: ' + e.origin
21
+ }
22
+ }
23
+ })
24
+
25
+ return {
26
+
27
+ on(name, callback) {
28
+ events[name] = callback
29
+ },
30
+
31
+ emit(event, ...payload) {
32
+ win.postMessage({ event, payload }, origin)
33
+ },
34
+
35
+ remove(name) {
36
+ delete events[name]
37
+ }
38
+ }
39
+ }
@@ -0,0 +1 @@
1
+ (function(n,i){typeof exports=="object"&&typeof module!="undefined"?i(exports):typeof define=="function"&&define.amd?define(["exports"],i):(n=typeof globalThis!="undefined"?globalThis:n||self,i(n.channel={}))})(this,(function(n){"use strict";const i=({target:s=null,accept:d=[],origin:f=location.origin})=>{const u=(s==null?void 0:s.contentWindow)||s,t={};return window.addEventListener("message",e=>{if(d.includes("*")||d.includes(e.origin)){const{payload:o,event:l}=e.data;t[l]&&t[l].apply(null,o)}else throw{type:"ACCESS DENIED",message:"Cant receive message from: "+e.origin}}),{on(e,o){t[e]=o},emit(e,...o){u.postMessage({event:e,payload:o},f)},remove(e){delete t[e]}}};n.Channel=i,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
@@ -1,96 +1,104 @@
1
- var T = Object.defineProperty, B = Object.defineProperties;
2
- var C = Object.getOwnPropertyDescriptors;
3
- var D = Object.getOwnPropertySymbols;
4
- var G = Object.prototype.hasOwnProperty, H = Object.prototype.propertyIsEnumerable;
5
- var A = (a, r, e) => r in a ? T(a, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[r] = e, m = (a, r) => {
1
+ var C = Object.defineProperty, G = Object.defineProperties;
2
+ var H = Object.getOwnPropertyDescriptors;
3
+ var h = Object.getOwnPropertySymbols;
4
+ var L = Object.prototype.hasOwnProperty, M = Object.prototype.propertyIsEnumerable;
5
+ var A = (t, r, e) => r in t ? C(t, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[r] = e, v = (t, r) => {
6
6
  for (var e in r || (r = {}))
7
- G.call(r, e) && A(a, e, r[e]);
8
- if (D)
9
- for (var e of D(r))
10
- H.call(r, e) && A(a, e, r[e]);
11
- return a;
12
- }, L = (a, r) => B(a, C(r));
13
- const M = "form-validation", g = "[data-validation]", J = "[data-mask]";
14
- function U({
15
- main: a,
7
+ L.call(r, e) && A(t, e, r[e]);
8
+ if (h)
9
+ for (var e of h(r))
10
+ M.call(r, e) && A(t, e, r[e]);
11
+ return t;
12
+ }, w = (t, r) => G(t, H(r));
13
+ var y = (t, r) => {
14
+ var e = {};
15
+ for (var a in t)
16
+ L.call(t, a) && r.indexOf(a) < 0 && (e[a] = t[a]);
17
+ if (t != null && h)
18
+ for (var a of h(t))
19
+ r.indexOf(a) < 0 && M.call(t, a) && (e[a] = t[a]);
20
+ return e;
21
+ };
22
+ const S = "form-validation", p = "[data-validation]", J = "[data-mask]";
23
+ function W({
24
+ main: t,
16
25
  elm: r,
17
26
  state: e,
18
- on: n,
19
- emit: v,
20
- dependencies: y,
21
- trigger: F
27
+ on: a,
28
+ emit: g,
29
+ dependencies: N,
30
+ trigger: O
22
31
  }) {
23
- var k;
24
- const { validations: h, masks: E } = y, f = (k = r.querySelector("input,select,textarea")) == null ? void 0 : k.form;
25
- let u = S(f);
26
- a((t) => {
27
- n("input", "input, textarea, select", z), n("input", J, $), n("input", g, p("input")), n("change", g, p("change")), n("blur", g, p("blur")), n("focus", "input, textarea, select", N), n("blur", "input, textarea, select", O), f.addEventListener("reset", j), f.addEventListener("submit", _), I();
28
- }), r.setValues = (t) => {
29
- e.set((s) => s.form.values = m(m({}, s.form.values), t));
32
+ var V;
33
+ const u = y(N, []), f = (V = r.querySelector("input,select,textarea")) == null ? void 0 : V.form;
34
+ let m = I(f);
35
+ t((s) => {
36
+ a("input", "input, textarea, select", j), a("input", J, K), a("input", p, b("input")), a("change", p, b("change")), a("blur", p, b("blur")), a("focus", "input, textarea, select", _), a("blur", "input, textarea, select", $), f.addEventListener("reset", T), f.addEventListener("submit", q), z();
37
+ }), r.setValues = (s) => {
38
+ e.set((o) => o.form.values = v(v({}, o.form.values), s));
30
39
  };
31
- const I = () => {
32
- if (!h)
40
+ const z = () => {
41
+ if (!u)
33
42
  throw new Error(
34
- "<form-validation> - No validations provided in dependencies"
43
+ "<form-validation> - No entities provided in dependencies"
35
44
  );
36
- const t = V();
37
- e.set((s) => s.form.values = t);
38
- }, V = () => {
39
- const t = {};
40
- return u.forEach((s) => t[s] = ""), t;
41
- }, N = (t) => {
42
- const s = t.target.name;
43
- e.set((o) => {
44
- o.form.touched[s] = !0, o.form.focused[s] = !0;
45
+ const s = E();
46
+ e.set((o) => o.form.values = s);
47
+ }, E = () => {
48
+ const s = {};
49
+ return m.forEach((o) => s[o] = ""), s;
50
+ }, _ = (s) => {
51
+ const o = s.target.name;
52
+ e.set((n) => {
53
+ n.form.touched[o] = !0, n.form.focused[o] = !0;
45
54
  });
46
- }, O = (t) => {
47
- const s = t.target.name;
48
- e.set((o) => {
49
- o.form.focused[s] = !1;
55
+ }, $ = (s) => {
56
+ const o = s.target.name;
57
+ e.set((n) => {
58
+ n.form.focused[o] = !1;
50
59
  });
51
- }, p = (t) => (s) => {
52
- const o = s.target, i = o.name, c = w(o, f), b = o.dataset.validation.split(/\s/), d = [], x = e.get();
53
- b.forEach((l) => {
54
- if (l in h) {
55
- const { ok: q, message: K } = h[l](
56
- c,
57
- o,
58
- f
59
- );
60
- q || d.push(K);
60
+ }, b = (s) => (o) => {
61
+ const n = o.target, c = n.name, l = F(n, f), k = n.dataset.validation.split(/\s/), d = [], x = e.get();
62
+ k.forEach((i) => {
63
+ if (i in u) {
64
+ const D = u[i];
65
+ if (!D.validate(l, n, f)) {
66
+ const B = D.message(l, n, f);
67
+ d.push(B);
68
+ }
61
69
  }
62
- }), d.length ? t === "input" ? (u.add(o.name), e.set((l) => {
63
- l.form.isValid = !1, x.form.errors[i] && d[0] != x.form.errors[i] && (l.form.errors[i] = d[0]);
64
- })) : (t === "blur" || t === "change") && (u.add(o.name), e.set((l) => {
65
- l.form.errors[i] = d[0], l.form.isValid = !1;
66
- })) : (u.delete(o.name), e.set((l) => {
67
- delete l.form.errors[i], u.size || (l.form.isValid = !0);
70
+ }), d.length ? s === "input" ? (m.add(n.name), e.set((i) => {
71
+ i.form.isValid = !1, x.form.errors[c] && d[0] != x.form.errors[c] && (i.form.errors[c] = d[0]);
72
+ })) : (s === "blur" || s === "change") && (m.add(n.name), e.set((i) => {
73
+ i.form.errors[c] = d[0], i.form.isValid = !1;
74
+ })) : (m.delete(n.name), e.set((i) => {
75
+ delete i.form.errors[c], m.size || (i.form.isValid = !0);
68
76
  }));
69
- }, z = (t) => {
70
- const { name: s } = t.target, o = w(t.target, f);
71
- e.set((i) => i.form.values[s] = o);
72
- }, _ = (t) => {
73
- t.preventDefault(), F("blur", g);
74
- const o = e.get().form.errors;
75
- if (Object.keys(o).length)
76
- v(`${M}:error`, { errors: o });
77
+ }, j = (s) => {
78
+ const { name: o } = s.target, n = F(s.target, f);
79
+ e.set((c) => c.form.values[o] = n);
80
+ }, q = (s) => {
81
+ s.preventDefault(), O("blur", p);
82
+ const n = e.get().form.errors;
83
+ if (Object.keys(n).length)
84
+ g(`${S}:error`, { errors: n });
77
85
  else {
78
- const c = Q(t.target);
79
- v(`${M}:submit`, m({}, c));
86
+ const l = Q(s.target);
87
+ g(`${S}:submit`, v({}, l));
80
88
  }
81
- }, $ = (t) => {
82
- let s = t.target.value;
83
- const { mask: o } = t.target.dataset;
84
- o.split(/s/).forEach((c) => {
85
- if (c && c in E) {
86
- const b = E[c];
87
- s = b(s, t.target, t.target.form);
89
+ }, K = (s) => {
90
+ let o = s.target.value;
91
+ const { mask: n } = s.target.dataset;
92
+ n.split(/s/).forEach((l) => {
93
+ if (u[l] && u[l].mask) {
94
+ const k = u[l].mask;
95
+ o = k(o, s.target, s.target.form);
88
96
  }
89
- }), e.set((c) => c.form.values[t.target.name] = s || "");
90
- }, j = () => {
91
- u = S(f), e.set({
92
- form: L(m({}, P.form), {
93
- values: V()
97
+ }), e.set((l) => l.form.values[s.target.name] = o || "");
98
+ }, T = () => {
99
+ m = I(f), e.set({
100
+ form: w(v({}, P.form), {
101
+ values: E()
94
102
  })
95
103
  });
96
104
  };
@@ -103,19 +111,19 @@ const P = {
103
111
  isValid: !1,
104
112
  focused: {}
105
113
  }
106
- }, Q = (a) => {
107
- const r = new FormData(a), e = {};
108
- for (let [n, v] of r)
109
- e[n] = v;
114
+ }, Q = (t) => {
115
+ const r = new FormData(t), e = {};
116
+ for (let [a, g] of r)
117
+ e[a] = g;
110
118
  return { formData: r, data: e };
111
- }, w = (a, r) => {
112
- const { name: e, type: n } = a;
113
- return n == "checkbox" ? a.checked ? a.value : "" : r[e].value;
114
- }, S = (a) => {
119
+ }, F = (t, r) => {
120
+ const { name: e, type: a } = t;
121
+ return a == "checkbox" ? t.checked ? t.value : "" : r[e].value;
122
+ }, I = (t) => {
115
123
  const r = /* @__PURE__ */ new Set();
116
- return Array.from(a.elements).filter((e) => e.name && e.dataset.validation).forEach((e) => r.add(e.name)), r;
124
+ return Array.from(t.elements).filter((e) => e.name && e.dataset.validation).forEach((e) => r.add(e.name)), r;
117
125
  };
118
126
  export {
119
- U as default,
127
+ W as default,
120
128
  P as model
121
129
  };
@@ -12,7 +12,7 @@ export default function formValidation({
12
12
  trigger,
13
13
  }) {
14
14
  //
15
- const { validations, masks } = dependencies
15
+ const { ...entities } = dependencies
16
16
  const form = elm.querySelector('input,select,textarea')?.form
17
17
  let fields = getFields(form)
18
18
 
@@ -36,9 +36,9 @@ export default function formValidation({
36
36
  }
37
37
 
38
38
  const initialValues = () => {
39
- if (!validations) {
39
+ if (!entities) {
40
40
  throw new Error(
41
- '<form-validation> - No validations provided in dependencies'
41
+ '<form-validation> - No entities provided in dependencies'
42
42
  )
43
43
  }
44
44
  const fields = getInitialValues()
@@ -75,13 +75,11 @@ export default function formValidation({
75
75
  const currentState = state.get()
76
76
 
77
77
  validationList.forEach((validation) => {
78
- if (validation in validations) {
79
- const { ok, message } = validations[validation](
80
- value,
81
- input,
82
- form
83
- )
78
+ if (validation in entities) {
79
+ const entity = entities[validation]
80
+ const ok = entity.validate( value, input, form )
84
81
  if (!ok) {
82
+ const message = entity.message( value, input, form)
85
83
  errorsList.push(message)
86
84
  }
87
85
  }
@@ -145,8 +143,8 @@ export default function formValidation({
145
143
  const allMasks = mask.split(/s/)
146
144
 
147
145
  allMasks.forEach((mask) => {
148
- if (mask && mask in masks) {
149
- const fn = masks[mask]
146
+ if (entities[mask] && entities[mask].mask) {
147
+ const fn = entities[mask].mask
150
148
  value = fn(value, e.target, e.target.form)
151
149
  }
152
150
  })
@@ -1 +1 @@
1
- (function(a,r){typeof exports=="object"&&typeof module!="undefined"?r(exports):typeof define=="function"&&define.amd?define(["exports"],r):(a=typeof globalThis!="undefined"?globalThis:a||self,r(a["form-validation"]={}))})(this,(function(a){"use strict";var H=Object.defineProperty,J=Object.defineProperties;var Q=Object.getOwnPropertyDescriptors;var L=Object.getOwnPropertySymbols;var R=Object.prototype.hasOwnProperty,U=Object.prototype.propertyIsEnumerable;var w=(a,r,n)=>r in a?H(a,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[r]=n,p=(a,r)=>{for(var n in r||(r={}))R.call(r,n)&&w(a,n,r[n]);if(L)for(var n of L(r))U.call(r,n)&&w(a,n,r[n]);return a},O=(a,r)=>J(a,Q(r));const r="form-validation",n="[data-validation]",T="[data-mask]";function _({main:f,elm:c,state:t,on:i,emit:h,dependencies:F,trigger:I}){var S;const{validations:b,masks:y}=F,m=(S=c.querySelector("input,select,textarea"))==null?void 0:S.form;let v=x(m);f(e=>{i("input","input, textarea, select",q),i("input",T,P),i("input",n,E("input")),i("change",n,E("change")),i("blur",n,E("blur")),i("focus","input, textarea, select",z),i("blur","input, textarea, select",$),m.addEventListener("reset",B),m.addEventListener("submit",K),N()}),c.setValues=e=>{t.set(s=>s.form.values=p(p({},s.form.values),e))};const N=()=>{if(!b)throw new Error("<form-validation> - No validations provided in dependencies");const e=D();t.set(s=>s.form.values=e)},D=()=>{const e={};return v.forEach(s=>e[s]=""),e},z=e=>{const s=e.target.name;t.set(o=>{o.form.touched[s]=!0,o.form.focused[s]=!0})},$=e=>{const s=e.target.name;t.set(o=>{o.form.focused[s]=!1})},E=e=>s=>{const o=s.target,u=o.name,d=M(o,m),V=o.dataset.validation.split(/\s/),g=[],A=t.get();V.forEach(l=>{if(l in b){const{ok:C,message:G}=b[l](d,o,m);C||g.push(G)}}),g.length?e==="input"?(v.add(o.name),t.set(l=>{l.form.isValid=!1,A.form.errors[u]&&g[0]!=A.form.errors[u]&&(l.form.errors[u]=g[0])})):(e==="blur"||e==="change")&&(v.add(o.name),t.set(l=>{l.form.errors[u]=g[0],l.form.isValid=!1})):(v.delete(o.name),t.set(l=>{delete l.form.errors[u],v.size||(l.form.isValid=!0)}))},q=e=>{const{name:s}=e.target,o=M(e.target,m);t.set(u=>u.form.values[s]=o)},K=e=>{e.preventDefault(),I("blur",n);const o=t.get().form.errors;if(Object.keys(o).length)h(`${r}:error`,{errors:o});else{const d=j(e.target);h(`${r}:submit`,p({},d))}},P=e=>{let s=e.target.value;const{mask:o}=e.target.dataset;o.split(/s/).forEach(d=>{if(d&&d in y){const V=y[d];s=V(s,e.target,e.target.form)}}),t.set(d=>d.form.values[e.target.name]=s||"")},B=()=>{v=x(m),t.set({form:O(p({},k.form),{values:D()})})}}const k={form:{errors:{},values:{},touched:{},isValid:!1,focused:{}}},j=f=>{const c=new FormData(f),t={};for(let[i,h]of c)t[i]=h;return{formData:c,data:t}},M=(f,c)=>{const{name:t,type:i}=f;return i=="checkbox"?f.checked?f.value:"":c[t].value},x=f=>{const c=new Set;return Array.from(f.elements).filter(t=>t.name&&t.dataset.validation).forEach(t=>c.add(t.name)),c};a.default=_,a.model=k,Object.defineProperties(a,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
1
+ (function(t,s){typeof exports=="object"&&typeof module!="undefined"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(t=typeof globalThis!="undefined"?globalThis:t||self,s(t["form-validation"]={}))})(this,(function(t){"use strict";var Q=Object.defineProperty,R=Object.defineProperties;var U=Object.getOwnPropertyDescriptors;var E=Object.getOwnPropertySymbols;var T=Object.prototype.hasOwnProperty,_=Object.prototype.propertyIsEnumerable;var O=(t,s,n)=>s in t?Q(t,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[s]=n,b=(t,s)=>{for(var n in s||(s={}))T.call(s,n)&&O(t,n,s[n]);if(E)for(var n of E(s))_.call(s,n)&&O(t,n,s[n]);return t},j=(t,s)=>R(t,U(s));var F=(t,s)=>{var n={};for(var i in t)T.call(t,i)&&s.indexOf(i)<0&&(n[i]=t[i]);if(t!=null&&E)for(var i of E(t))s.indexOf(i)<0&&_.call(t,i)&&(n[i]=t[i]);return n};const s="form-validation",n="[data-validation]",i="[data-mask]";function I({main:d,elm:f,state:o,on:l,emit:k,dependencies:z,trigger:$}){var A;const g=F(z,[]),v=(A=f.querySelector("input,select,textarea"))==null?void 0:A.form;let p=D(v);d(e=>{l("input","input, textarea, select",B),l("input",i,G),l("input",n,V("input")),l("change",n,V("change")),l("blur",n,V("blur")),l("focus","input, textarea, select",K),l("blur","input, textarea, select",P),v.addEventListener("reset",H),v.addEventListener("submit",C),q()}),f.setValues=e=>{o.set(r=>r.form.values=b(b({},r.form.values),e))};const q=()=>{if(!g)throw new Error("<form-validation> - No entities provided in dependencies");const e=S();o.set(r=>r.form.values=e)},S=()=>{const e={};return p.forEach(r=>e[r]=""),e},K=e=>{const r=e.target.name;o.set(a=>{a.form.touched[r]=!0,a.form.focused[r]=!0})},P=e=>{const r=e.target.name;o.set(a=>{a.form.focused[r]=!1})},V=e=>r=>{const a=r.target,m=a.name,u=x(a,v),y=a.dataset.validation.split(/\s/),h=[],L=o.get();y.forEach(c=>{if(c in g){const w=g[c];if(!w.validate(u,a,v)){const J=w.message(u,a,v);h.push(J)}}}),h.length?e==="input"?(p.add(a.name),o.set(c=>{c.form.isValid=!1,L.form.errors[m]&&h[0]!=L.form.errors[m]&&(c.form.errors[m]=h[0])})):(e==="blur"||e==="change")&&(p.add(a.name),o.set(c=>{c.form.errors[m]=h[0],c.form.isValid=!1})):(p.delete(a.name),o.set(c=>{delete c.form.errors[m],p.size||(c.form.isValid=!0)}))},B=e=>{const{name:r}=e.target,a=x(e.target,v);o.set(m=>m.form.values[r]=a)},C=e=>{e.preventDefault(),$("blur",n);const a=o.get().form.errors;if(Object.keys(a).length)k(`${s}:error`,{errors:a});else{const u=N(e.target);k(`${s}:submit`,b({},u))}},G=e=>{let r=e.target.value;const{mask:a}=e.target.dataset;a.split(/s/).forEach(u=>{if(g[u]&&g[u].mask){const y=g[u].mask;r=y(r,e.target,e.target.form)}}),o.set(u=>u.form.values[e.target.name]=r||"")},H=()=>{p=D(v),o.set({form:j(b({},M.form),{values:S()})})}}const M={form:{errors:{},values:{},touched:{},isValid:!1,focused:{}}},N=d=>{const f=new FormData(d),o={};for(let[l,k]of f)o[l]=k;return{formData:f,data:o}},x=(d,f)=>{const{name:o,type:l}=d;return l=="checkbox"?d.checked?d.value:"":f[o].value},D=d=>{const f=new Set;return Array.from(d.elements).filter(o=>o.name&&o.dataset.validation).forEach(o=>f.add(o.name)),f};t.default=I,t.model=M,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
@@ -44,9 +44,9 @@ on('form-validation:error', ({ errors }) => {})
44
44
  ##### main.ts
45
45
  ```ts
46
46
  import * as formValidation from 'jails.stdlib/form-validation'
47
- import rules from './my-custom-rules'
47
+ import * as entities from './my-entities'
48
48
 
49
- jails.register('form-validation', formValidation, { ...rules })
49
+ jails.register('form-validation', formValidation, { ...entities })
50
50
  jails.start()
51
51
  ```
52
52
 
@@ -84,37 +84,62 @@ jails.start()
84
84
  ```
85
85
 
86
86
  ##### my-custom-rules/index.ts
87
+ You need to provide a map of entities that will be used to validate the kind of your form fields.
88
+ They all need to implement: `validate()`, `message()`. Optional: `mask()`.
89
+
90
+ ##### Example
91
+
87
92
  ```ts
88
- export default {
89
-
90
- validations : {
91
-
92
- required(value, input, form) {
93
- if (!value) return { ok: false, message: 'This field is required'}
94
- return { ok: true }
95
- },
96
-
97
- email(value, input, form) {
98
- if (!value) return { ok: true }
99
- if (!value.match(/(.*)@(.*)\.\w{2,}/)) return { ok: false, message: 'Invalid email' }
100
- return { ok: true }
101
- },
102
-
103
- number(value, input, form) {
104
- if (value.match(/\D/g)) return { ok: false, message:'This field takes only number' }
105
- return { ok: true }
106
- }
93
+ import * as formValidation from 'jails.stdlib/form-validation'
94
+ import { email, number, required } from './my-entities'
95
+
96
+ jails.register('form-validation', formValidation, { email, number, required })
97
+ jails.start()
98
+ ```
99
+
100
+ **./my-entities.ts**
101
+
102
+ ```ts
103
+ export const email = {
104
+ validate( value, input, form ) {
105
+ if (!value) return true
106
+ if (!value.match(/(.*)@(.*)\.\w{2,}/)) return false
107
+ return true
108
+ },
109
+ mask() {
110
+ // I don't have a mask
107
111
  },
112
+ message( value, input, form ) {
113
+ return `Invalid Email`
114
+ }
115
+ }
108
116
 
109
- masks: {
110
- number(value, input, form) {
111
- return value.replace(/\D/, '')
112
- }
117
+ export const required = {
118
+ validate(value, input, form) {
119
+ if (!value) return false
120
+ return true
121
+ },
122
+ mask(value, input, form) {
123
+ // I don't have a mask
124
+ },
125
+ message(value, input, form) {
126
+ return `This field is required`
127
+ }
128
+ }
129
+
130
+ export const number = {
131
+ validate(value, input, form) {
132
+ if (value.match(/\D/g)) return false
133
+ return true
134
+ },
135
+ mask(value, input, form) {
136
+ return value.replace(/\D/, '')
137
+ },
138
+ message() {
139
+ return `This field accepts only number`
113
140
  }
114
141
  }
115
142
  ```
116
-
117
- To see how to inject this dependency, go back to the [usage](#usage) section.
118
143
 
119
144
 
120
145
  ##### element.setValues(...data)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jails.stdlib",
3
- "version": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "description": "The Jails Standard Library",
5
5
  "types": "index.d.ts",
6
6
  "repository": {
@@ -1,109 +0,0 @@
1
- # messenger
2
-
3
- ```ts
4
- messenger({
5
- target?: Window | HTMLIFrameElement,
6
- accept?: string[],
7
- actions?: Record<string, (payload: any) => void>,
8
- origin?: string
9
- })
10
- ```
11
- # ๐Ÿ“ฌ Messenger API Documentation
12
-
13
- The `messenger` utility provides a lightweight, secure interface for sending and receiving messages between windows or iframes using `postMessage`.
14
-
15
- ---
16
-
17
- ## โœ… Features
18
-
19
- * Easy dispatch and subscription to custom message actions.
20
- * Secure origin validation.
21
- * Works with iframes or separate window contexts.
22
- * Extensible via `subscribe`.
23
-
24
- ---
25
-
26
- ## ๐Ÿงช Usage
27
-
28
- ### Parent Page
29
-
30
- ```ts
31
- import { messenger } from 'jails.stdlib/messenger'
32
-
33
- const msg = messenger({
34
- target: document.getElementById('myIframe'), // <iframe id="myIframe" />
35
- accept: ['https://child-app.com'], // Allowed origins
36
- actions: {
37
- reply(data) {
38
- console.log('Received from iframe:', data)
39
- }
40
- }
41
- })
42
-
43
- // Send message to iframe
44
- msg.dispatch('init', { user: 'Alice' })
45
-
46
- // Add more listeners later
47
- msg.subscribe({
48
- status: (msg) => console.log('Status update:', msg)
49
- })
50
- ```
51
-
52
- ### Iframe Page
53
-
54
- ```ts
55
- const msg = messenger({
56
- target: window.parent,
57
- accept: ['https://parent-app.com'],
58
- actions: {
59
- init(data){
60
- console.log('Init from parent:', data)
61
- msg.dispatch('reply', { received: true })
62
- }
63
- }
64
- })
65
- ```
66
-
67
- ---
68
-
69
- ## ๐Ÿงน API
70
-
71
- ### `messenger(options)`
72
-
73
- Creates a new Messenger instance.
74
-
75
- #### Options:
76
-
77
- | Option | Type | Description |
78
- | --------- | ----------------------------- | --------------------------------------- |
79
- | `target` | `Window \| HTMLIFrameElement` | Target to send messages to |
80
- | `accept` | `string[]` | Allowed origins (`['*']` to accept all) |
81
- | `actions` | `Record<string, Function>` | Message handlers keyed by action name |
82
- | `origin` | `string` | The origin used when sending messages |
83
-
84
- ---
85
-
86
- ### `.dispatch(action: string, payload?: any)`
87
-
88
- Sends a message to the target window.
89
-
90
- ```ts
91
- msg.dispatch('sayHello', { name: 'Bob' })
92
- ```
93
-
94
- ---
95
-
96
- ### `.subscribe(newActions: Record<string, Function>)`
97
-
98
- Adds more actions to the messenger at runtime.
99
-
100
- ```ts
101
- msg.subscribe({ logout: () => console.log('Logging out...') })
102
- ```
103
-
104
- ---
105
-
106
- ## ๐Ÿ”’ Security Notes
107
-
108
- * Always **specify allowed origins** in `accept` to avoid cross-site scripting risks.
109
- * Avoid using `'*'` unless absolutely necessary (e.g., during development).
@@ -1,9 +0,0 @@
1
- export declare const messenger: ({ target, accept, actions, origin }?: {
2
- target?: any;
3
- accept?: any;
4
- actions?: any;
5
- origin?: string;
6
- }) => {
7
- dispatch(action: string, payload?: any): void;
8
- subscribe(actions_: any): void;
9
- };
@@ -1,39 +0,0 @@
1
- var w = Object.defineProperty;
2
- var l = Object.getOwnPropertySymbols;
3
- var a = Object.prototype.hasOwnProperty, p = Object.prototype.propertyIsEnumerable;
4
- var r = (n, i, s) => i in n ? w(n, i, { enumerable: !0, configurable: !0, writable: !0, value: s }) : n[i] = s, d = (n, i) => {
5
- for (var s in i || (i = {}))
6
- a.call(i, s) && r(n, s, i[s]);
7
- if (l)
8
- for (var s of l(i))
9
- p.call(i, s) && r(n, s, i[s]);
10
- return n;
11
- };
12
- const f = ({
13
- target: n = null,
14
- accept: i = [],
15
- actions: s = {},
16
- origin: c = location.origin
17
- } = {}) => {
18
- const m = (n == null ? void 0 : n.contentWindow) || n;
19
- return window.addEventListener("message", (e) => {
20
- if (i.includes("*") || i.includes(e.origin)) {
21
- const { action: o, payload: u } = e.data;
22
- o in s && s[o](u);
23
- } else
24
- throw {
25
- type: "ACCESS DENIED",
26
- message: "Cant receive message from: " + e.origin
27
- };
28
- }), {
29
- dispatch(e, o) {
30
- m.postMessage({ action: e, payload: o }, c);
31
- },
32
- subscribe(e) {
33
- s = d(d({}, e), s);
34
- }
35
- };
36
- };
37
- export {
38
- f as messenger
39
- };
@@ -1,38 +0,0 @@
1
-
2
- export const messenger = ({
3
-
4
- target = null as any,
5
- accept = [] as any,
6
- actions = {} as any,
7
- origin = location.origin
8
-
9
- } = {}) => {
10
-
11
- const win = target?.contentWindow || target
12
-
13
- window.addEventListener('message', ( event ) => {
14
-
15
- if( accept.includes('*') || accept.includes(event.origin) ) {
16
- const { action, payload } = event.data
17
- if( action in actions ) {
18
- actions[ action ]( payload as any )
19
- }
20
- } else {
21
- throw {
22
- type : 'ACCESS DENIED',
23
- message : 'Cant receive message from: ' + event.origin
24
- }
25
- }
26
- })
27
-
28
- return {
29
-
30
- dispatch( action: string, payload?: any ) {
31
- win.postMessage({ action, payload }, origin)
32
- },
33
-
34
- subscribe( actions_: any ) {
35
- actions = { ...actions_, ...actions }
36
- }
37
- }
38
- }
@@ -1 +0,0 @@
1
- (function(i,e){typeof exports=="object"&&typeof module!="undefined"?e(exports):typeof define=="function"&&define.amd?define(["exports"],e):(i=typeof globalThis!="undefined"?globalThis:i||self,e(i.messenger={}))})(this,(function(i){"use strict";var p=Object.defineProperty;var u=Object.getOwnPropertySymbols;var g=Object.prototype.hasOwnProperty,y=Object.prototype.propertyIsEnumerable;var l=(i,e,n)=>e in i?p(i,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):i[e]=n,f=(i,e)=>{for(var n in e||(e={}))g.call(e,n)&&l(i,n,e[n]);if(u)for(var n of u(e))y.call(e,n)&&l(i,n,e[n]);return i};const e=({target:n=null,accept:t=[],actions:o={},origin:r=location.origin}={})=>{const c=(n==null?void 0:n.contentWindow)||n;return window.addEventListener("message",s=>{if(t.includes("*")||t.includes(s.origin)){const{action:d,payload:m}=s.data;d in o&&o[d](m)}else throw{type:"ACCESS DENIED",message:"Cant receive message from: "+s.origin}}),{dispatch(s,d){c.postMessage({action:s,payload:d},r)},subscribe(s){o=f(f({},s),o)}}};i.messenger=e,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})}));