@junojs/core 0.1.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +75 -0
  3. package/dist/cli/cli.d.ts +12 -0
  4. package/dist/cli/cli.d.ts.map +1 -0
  5. package/dist/cli.cjs +88 -0
  6. package/dist/cli.cjs.map +1 -0
  7. package/dist/cli.js +238 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/common/forms/form-model.d.ts +29 -0
  10. package/dist/common/forms/form-model.d.ts.map +1 -0
  11. package/dist/common/forms/index.d.ts +4 -0
  12. package/dist/common/forms/index.d.ts.map +1 -0
  13. package/dist/common/forms/schema.d.ts +33 -0
  14. package/dist/common/forms/schema.d.ts.map +1 -0
  15. package/dist/common/forms/validators.d.ts +18 -0
  16. package/dist/common/forms/validators.d.ts.map +1 -0
  17. package/dist/common/http/http.service.d.ts +25 -0
  18. package/dist/common/http/http.service.d.ts.map +1 -0
  19. package/dist/common/http/index.d.ts +3 -0
  20. package/dist/common/http/index.d.ts.map +1 -0
  21. package/dist/common/i18n/i18n.service.d.ts +36 -0
  22. package/dist/common/i18n/i18n.service.d.ts.map +1 -0
  23. package/dist/common/i18n/index.d.ts +2 -0
  24. package/dist/common/i18n/index.d.ts.map +1 -0
  25. package/dist/common/router/index.d.ts +2 -0
  26. package/dist/common/router/index.d.ts.map +1 -0
  27. package/dist/common/router/router.service.d.ts +46 -0
  28. package/dist/common/router/router.service.d.ts.map +1 -0
  29. package/dist/core/bootstrap.d.ts +3 -0
  30. package/dist/core/bootstrap.d.ts.map +1 -0
  31. package/dist/core/decorators.d.ts +56 -0
  32. package/dist/core/decorators.d.ts.map +1 -0
  33. package/dist/core/dom.d.ts +6 -0
  34. package/dist/core/dom.d.ts.map +1 -0
  35. package/dist/core/engine.d.ts +7 -0
  36. package/dist/core/engine.d.ts.map +1 -0
  37. package/dist/core/error-handler.d.ts +34 -0
  38. package/dist/core/error-handler.d.ts.map +1 -0
  39. package/dist/core/index.d.ts +9 -0
  40. package/dist/core/index.d.ts.map +1 -0
  41. package/dist/core/persist.d.ts +15 -0
  42. package/dist/core/persist.d.ts.map +1 -0
  43. package/dist/core/reactivity.d.ts +3 -0
  44. package/dist/core/reactivity.d.ts.map +1 -0
  45. package/dist/index.cjs +2 -0
  46. package/dist/index.cjs.map +1 -0
  47. package/dist/index.d.ts +8 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +896 -0
  50. package/dist/index.js.map +1 -0
  51. package/package.json +67 -0
package/dist/index.js ADDED
@@ -0,0 +1,896 @@
1
+ var C = Object.defineProperty;
2
+ var k = (i, t, e) => t in i ? C(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
3
+ var h = (i, t, e) => k(i, typeof t != "symbol" ? t + "" : t, e);
4
+ import "reflect-metadata";
5
+ function J(i) {
6
+ return (t) => {
7
+ i.shadow === void 0 && (i.shadow = !0), Reflect.defineMetadata("nf:config", i, t);
8
+ };
9
+ }
10
+ function W() {
11
+ return (i, t) => {
12
+ const e = Reflect.getMetadata("nf:states", i) || [];
13
+ e.push(t), Reflect.defineMetadata("nf:states", e, i);
14
+ };
15
+ }
16
+ function K() {
17
+ return (i, t) => {
18
+ const e = Reflect.getMetadata("nf:inputs", i) || [];
19
+ e.push(t), Reflect.defineMetadata("nf:inputs", e, i);
20
+ };
21
+ }
22
+ function z(i) {
23
+ return (t, e) => {
24
+ const s = Reflect.getMetadata("nf:params", t) || [];
25
+ s.push({ key: e, paramName: i || e }), Reflect.defineMetadata("nf:params", s, t);
26
+ };
27
+ }
28
+ function G(i) {
29
+ return (t, e) => {
30
+ Reflect.defineMetadata("nf:inject", i, t, e);
31
+ };
32
+ }
33
+ function Q() {
34
+ return (i, t) => {
35
+ const e = Reflect.getMetadata("nf:transforms", i) || [];
36
+ e.push(t), Reflect.defineMetadata("nf:transforms", e, i);
37
+ };
38
+ }
39
+ function X() {
40
+ return (i, t) => {
41
+ const e = Reflect.getMetadata("nf:actions", i) || [];
42
+ e.push(t), Reflect.defineMetadata("nf:actions", e, i);
43
+ };
44
+ }
45
+ function B(i) {
46
+ return (t, e) => {
47
+ const s = Reflect.getMetadata("nf:provides", t) || [];
48
+ s.push({ key: i, property: e }), Reflect.defineMetadata("nf:provides", s, t);
49
+ };
50
+ }
51
+ function Y(i) {
52
+ return (t, e) => {
53
+ const s = Reflect.getMetadata("nf:injects", t) || [];
54
+ s.push({ key: i, property: e }), Reflect.defineMetadata("nf:injects", s, t);
55
+ };
56
+ }
57
+ function Z(i) {
58
+ return (t) => {
59
+ const e = Reflect.getMetadata("nf:refine", t) || [];
60
+ e.push(i), Reflect.defineMetadata("nf:refine", e, t);
61
+ };
62
+ }
63
+ function tt(i, t) {
64
+ return (e, s) => {
65
+ const n = Reflect.getMetadata("nf:validates", e) || [];
66
+ n.push({ key: s, predicate: i, message: t }), Reflect.defineMetadata("nf:validates", n, e);
67
+ };
68
+ }
69
+ function et(i) {
70
+ return (t, e) => {
71
+ Reflect.defineMetadata("nf:intercept", i, t, e);
72
+ };
73
+ }
74
+ function st(i) {
75
+ return (t) => {
76
+ Reflect.defineMetadata("nf:canActivate", i, t);
77
+ };
78
+ }
79
+ function nt() {
80
+ return (i, t) => {
81
+ const e = Reflect.getMetadata("nf:host-properties", i) || [];
82
+ e.push(t), Reflect.defineMetadata("nf:host-properties", e, i);
83
+ };
84
+ }
85
+ function it(i) {
86
+ return (t) => {
87
+ Reflect.defineMetadata("nf:schema", i, t);
88
+ };
89
+ }
90
+ function rt(i = "local") {
91
+ return (t, e) => {
92
+ const s = Reflect.getMetadata("nf:persist", t) || [];
93
+ s.push({
94
+ property: e,
95
+ storage: i,
96
+ key: `nf:${t.constructor.name}:${e}`
97
+ }), Reflect.defineMetadata("nf:persist", s, t);
98
+ };
99
+ }
100
+ function $(i) {
101
+ if (!(typeof window > "u"))
102
+ return i === "session" ? window.sessionStorage : window.localStorage;
103
+ }
104
+ function j(i) {
105
+ const t = Reflect.getMetadata("nf:persist", i) || [];
106
+ for (const e of t) {
107
+ const s = $(e.storage);
108
+ if (!s) continue;
109
+ const n = s.getItem(e.key);
110
+ if (n !== null)
111
+ try {
112
+ i[e.property] = JSON.parse(n);
113
+ } catch {
114
+ i[e.property] = n;
115
+ }
116
+ }
117
+ }
118
+ function O(i, t, e) {
119
+ const n = (Reflect.getMetadata("nf:persist", i) || []).find((r) => r.property === t);
120
+ if (n) {
121
+ const r = $(n.storage);
122
+ r && r.setItem(n.key, JSON.stringify(e));
123
+ }
124
+ }
125
+ function q(i, t) {
126
+ const e = Reflect.getMetadata("nf:states", i) || [], s = Reflect.getMetadata("nf:inputs", i) || [], n = [...e, ...s, "errors"];
127
+ let r;
128
+ return r = new Proxy(i, {
129
+ set(o, a, c) {
130
+ const l = o[a];
131
+ return o[a] = c, n.includes(a) && l !== c && (O(o, a, c), t()), !0;
132
+ },
133
+ get(o, a) {
134
+ const c = o[a];
135
+ return typeof c == "function" ? c.bind(r) : c;
136
+ }
137
+ }), r;
138
+ }
139
+ class D {
140
+ static render(t, e) {
141
+ const r = new DOMParser().parseFromString(`<div>${t}</div>`, "text/html").body.firstElementChild;
142
+ return r ? (this.processNode(r, e), r) : document.createElement("div");
143
+ }
144
+ static processNode(t, e) {
145
+ var c, l, f, p;
146
+ if (t.nodeType === Node.TEXT_NODE) {
147
+ t.textContent = this.interpolate(t.textContent || "", e);
148
+ return;
149
+ }
150
+ if (t.nodeType !== Node.ELEMENT_NODE) return;
151
+ const s = t, n = s.tagName.toLowerCase();
152
+ if (n === "for") {
153
+ const m = (((c = s.getAttribute("each")) == null ? void 0 : c.trim()) || "").replace(/^\{/, "").replace(/\}$/, "").match(/(\w+)\s+in\s+(.+)/);
154
+ if (m) {
155
+ const g = m[1], y = m[2], v = this.evaluateExpression(y, e), A = document.createDocumentFragment();
156
+ Array.isArray(v) && v.forEach((E) => {
157
+ const w = Object.create(e);
158
+ w[g] = E;
159
+ const P = s.cloneNode(!0);
160
+ for (Array.from(P.childNodes).forEach((I) => this.processNode(I, w)); P.firstChild; )
161
+ A.appendChild(P.firstChild);
162
+ }), (l = s.parentNode) == null || l.replaceChild(A, s);
163
+ }
164
+ return;
165
+ }
166
+ if (n === "if") {
167
+ const d = (((f = s.getAttribute("condition")) == null ? void 0 : f.trim()) || "").replace(/^\{/, "").replace(/\}$/, "");
168
+ let m = !1;
169
+ try {
170
+ m = !!new Function("ctx", `with(ctx) { return ${d} }`)(e);
171
+ } catch (E) {
172
+ console.error(`JunoEngine condition error: ${d}`, E);
173
+ }
174
+ const g = document.createDocumentFragment(), y = Array.from(s.childNodes), v = y.findIndex((E) => {
175
+ var w;
176
+ return ((w = E.tagName) == null ? void 0 : w.toLowerCase()) === "else";
177
+ });
178
+ (m ? v !== -1 ? y.slice(0, v) : y : v !== -1 ? Array.from(y[v].childNodes) : []).forEach((E) => {
179
+ const w = E.cloneNode(!0);
180
+ this.processNode(w, e), g.appendChild(w);
181
+ }), (p = s.parentNode) == null || p.replaceChild(g, s);
182
+ return;
183
+ }
184
+ const r = Array.from(s.attributes), o = n.includes("-");
185
+ r.forEach((u) => {
186
+ const d = /^\{[^{}]+\}$/.test(u.value);
187
+ if (o && d) {
188
+ const m = u.value.slice(1, -1), g = this.evaluateExpression(m, e), y = u.name.replace(/-([a-z])/g, (v) => v[1].toUpperCase());
189
+ s[y] = g;
190
+ } else {
191
+ const m = this.interpolate(u.value, e);
192
+ m !== u.value && s.setAttribute(u.name, m);
193
+ }
194
+ }), Array.from(s.childNodes).forEach((u) => this.processNode(u, e));
195
+ }
196
+ static evaluateExpression(t, e) {
197
+ const s = t.trim().split("|").map((c) => c.trim()), n = s[0], r = s[1], o = e.__transforms__ || {};
198
+ let a;
199
+ try {
200
+ /^[\w.]+$/.test(n) ? a = n.split(".").reduce((c, l) => c == null ? void 0 : c[l], e) : a = new Function("ctx", `with(ctx) { return ${n} }`)(e);
201
+ } catch {
202
+ return;
203
+ }
204
+ return r && o[r] && (a = o[r](a)), a;
205
+ }
206
+ static interpolate(t, e) {
207
+ return t.replace(/\{((?:[^{}]|\{[^{}]*\})*)\}/g, (s, n) => {
208
+ const r = this.evaluateExpression(n, e);
209
+ return r !== void 0 ? String(r) : "";
210
+ });
211
+ }
212
+ }
213
+ function U(i, t) {
214
+ let e;
215
+ typeof t == "string" ? e = new DOMParser().parseFromString(`<body>${t}</body>`, "text/html").body : e = t;
216
+ const s = i instanceof ShadowRoot ? i : document, n = s.activeElement, r = n && n.id ? `#${n.id}` : null, o = n ? n.selectionStart : null, a = n ? n.selectionEnd : null;
217
+ if (L(i, e, i), r) {
218
+ const c = i.querySelector(r);
219
+ c && c !== s.activeElement && (c.focus(), o !== null && a !== null && c.setSelectionRange(o, a));
220
+ }
221
+ }
222
+ function L(i, t, e) {
223
+ const s = Array.from(i.childNodes), n = Array.from(t.childNodes), r = Math.max(s.length, n.length);
224
+ for (let o = 0; o < r; o++) {
225
+ const a = s[o], c = n[o];
226
+ if (!a) {
227
+ i.appendChild(c);
228
+ continue;
229
+ }
230
+ if (!c) {
231
+ i.removeChild(a);
232
+ continue;
233
+ }
234
+ if (a.nodeType !== c.nodeType || a.tagName !== c.tagName) {
235
+ i.replaceChild(c, a);
236
+ continue;
237
+ }
238
+ if (a.nodeType === Node.TEXT_NODE) {
239
+ a.textContent !== c.textContent && (a.textContent = c.textContent);
240
+ continue;
241
+ }
242
+ if (a.nodeType === Node.ELEMENT_NODE) {
243
+ const l = a, f = c, p = l.getAttributeNames(), u = f.getAttributeNames();
244
+ for (const d of p)
245
+ f.hasAttribute(d) || l.removeAttribute(d);
246
+ for (const d of u) {
247
+ const m = f.getAttribute(d);
248
+ l.getAttribute(d) !== m && l.setAttribute(d, m);
249
+ const g = d.replace(/-([a-z])/g, (y) => y[1].toUpperCase());
250
+ l.tagName.includes("-") && f[g] !== void 0 && (l[g] = f[g]);
251
+ }
252
+ if (l instanceof HTMLInputElement || l instanceof HTMLTextAreaElement) {
253
+ const d = f.value || f.getAttribute("value") || "";
254
+ l.value !== d && (l.value = d);
255
+ }
256
+ (!l.tagName.includes("-") || l === e) && L(l, f, e);
257
+ }
258
+ }
259
+ }
260
+ const x = class x {
261
+ constructor() {
262
+ h(this, "routes", []);
263
+ h(this, "listeners", []);
264
+ h(this, "lastTab", null);
265
+ h(this, "lastParams", {});
266
+ typeof window < "u" && (window.addEventListener("popstate", () => this.handleLocationChange()), window.addEventListener("hashchange", () => this.handleLocationChange()));
267
+ }
268
+ static get instance() {
269
+ return x._instance || (x._instance = new x()), x._instance;
270
+ }
271
+ /**
272
+ * Register available routes.
273
+ */
274
+ register(t) {
275
+ this.routes = t;
276
+ }
277
+ /**
278
+ * Programmatically navigate to a path.
279
+ */
280
+ navigate(t, e = !0) {
281
+ if (typeof window > "u") return;
282
+ const s = t.startsWith("/") ? t : `/${t}`;
283
+ window.location.pathname !== s && (window.history.pushState({}, "", s), e && this.handleLocationChange());
284
+ }
285
+ /**
286
+ * Subscribe to route changes.
287
+ */
288
+ onRouteMatch(t) {
289
+ return this.listeners.push(t), this.lastTab !== null ? t(this.lastTab, this.lastParams) : this.handleLocationChange(), () => {
290
+ this.listeners = this.listeners.filter((e) => e !== t);
291
+ };
292
+ }
293
+ /**
294
+ * Manually trigger initial route matching (e.g. on page load).
295
+ */
296
+ init() {
297
+ this.handleLocationChange();
298
+ }
299
+ async handleLocationChange() {
300
+ if (typeof window > "u") return;
301
+ const t = window.location.pathname;
302
+ let e, s = {};
303
+ for (const n of this.routes) {
304
+ if (n.path === t || `/${n.tab}` === t) {
305
+ e = n;
306
+ break;
307
+ }
308
+ if (n.path.includes("/:")) {
309
+ const r = n.path.split("/"), o = t.split("/");
310
+ if (r.length === o.length) {
311
+ let a = !0;
312
+ const c = {};
313
+ for (let l = 0; l < r.length; l++)
314
+ if (r[l].startsWith(":"))
315
+ c[r[l].substring(1)] = o[l];
316
+ else if (r[l] !== o[l]) {
317
+ a = !1;
318
+ break;
319
+ }
320
+ if (a) {
321
+ e = n, s = c;
322
+ break;
323
+ }
324
+ }
325
+ }
326
+ }
327
+ if (e) {
328
+ if (e.canActivate)
329
+ try {
330
+ const n = await e.canActivate();
331
+ if (n === !1)
332
+ return;
333
+ if (typeof n == "string") {
334
+ this.navigate(n);
335
+ return;
336
+ }
337
+ } catch (n) {
338
+ console.error(`Route guard error on ${e.path}:`, n);
339
+ return;
340
+ }
341
+ e.title && (document.title = e.title), this.notify(e.tab, s);
342
+ } else if (t === "/" || t === "") {
343
+ const n = this.routes[0];
344
+ n && this.notify(n.tab, {});
345
+ }
346
+ }
347
+ notify(t, e) {
348
+ this.lastTab = t, this.lastParams = e, this.listeners.forEach((s) => s(t, e));
349
+ }
350
+ /**
351
+ * Get the current path.
352
+ */
353
+ get currentPath() {
354
+ return typeof window < "u" ? window.location.pathname : "/";
355
+ }
356
+ };
357
+ h(x, "_instance");
358
+ let N = x;
359
+ async function at(i) {
360
+ const t = Reflect.getMetadata("nf:config", i);
361
+ if (!t || !t.tag)
362
+ throw new Error("Missing @Component decorator or tag!");
363
+ customElements.define(
364
+ t.tag,
365
+ class extends HTMLElement {
366
+ constructor() {
367
+ super();
368
+ h(this, "instance");
369
+ h(this, "proxy");
370
+ h(this, "target");
371
+ h(this, "routeUnsubscribe");
372
+ this.instance = new i(), (Reflect.getMetadata("nf:host-properties", i.prototype) || []).forEach((r) => {
373
+ this.instance[r] = this;
374
+ }), (Reflect.getMetadata("nf:inputs", i.prototype) || []).forEach((r) => {
375
+ let o = this.hasOwnProperty(r) ? this[r] : void 0;
376
+ Object.defineProperty(this, r, {
377
+ get: () => this.proxy[r],
378
+ set: (a) => {
379
+ this.proxy[r] = a, this.update();
380
+ }
381
+ }), o !== void 0 && (this.instance[r] = o);
382
+ }), this.instance.errors || (this.instance.errors = {}), this.instance.isValid || (this.instance.isValid = () => {
383
+ this.proxy.errors = {};
384
+ let r = !0;
385
+ const o = Reflect.getMetadata("nf:schema", i), a = Reflect.getMetadata("nf:refine", i) || [], c = Reflect.getMetadata("nf:validates", i.prototype) || [], l = [];
386
+ if (o && typeof o.parse == "function") {
387
+ const f = o.parse(this.proxy);
388
+ f instanceof Promise ? l.push(f.then((p) => {
389
+ p.success || (r = !1, this.proxy.errors = { ...this.proxy.errors, ...p.errors });
390
+ })) : f.success || (r = !1, this.proxy.errors = { ...this.proxy.errors, ...f.errors });
391
+ }
392
+ for (const f of c) {
393
+ const p = this.proxy[f.key], u = f.predicate(p);
394
+ u instanceof Promise ? l.push(
395
+ u.then((d) => {
396
+ d || (r = !1, this.proxy.errors = { ...this.proxy.errors, [f.key]: f.message });
397
+ })
398
+ ) : u || (r = !1, this.proxy.errors = { ...this.proxy.errors, [f.key]: f.message });
399
+ }
400
+ for (const f of a) {
401
+ const p = f.validate(this.proxy);
402
+ if (p instanceof Promise)
403
+ l.push(
404
+ p.then((u) => {
405
+ if (!u) {
406
+ r = !1;
407
+ const d = f.fields[f.fields.length - 1];
408
+ this.proxy.errors = { ...this.proxy.errors, [d]: f.message };
409
+ }
410
+ })
411
+ );
412
+ else if (!p) {
413
+ r = !1;
414
+ const u = f.fields[f.fields.length - 1];
415
+ this.proxy.errors = { ...this.proxy.errors, [u]: f.message };
416
+ }
417
+ }
418
+ return l.length > 0 ? Promise.all(l).then(() => r) : r;
419
+ }), j(this.instance), this.proxy = q(this.instance, () => this.update()), t.shadow ? this.target = this.shadowRoot || this.attachShadow({ mode: "open" }) : this.target = this;
420
+ const n = (r, o) => {
421
+ let a = r.target;
422
+ for (; a && a !== this.parentElement; ) {
423
+ const c = a.getAttribute(o);
424
+ if (c) {
425
+ const l = c.match(/^(\w+)(?:\((.*)\))?$/);
426
+ if (l) {
427
+ const [f, p, u] = l, d = this.proxy[p];
428
+ if (typeof d == "function") {
429
+ const m = Reflect.getMetadata("nf:intercept", this.instance, p);
430
+ if (m) {
431
+ const g = m(this.proxy);
432
+ if (g instanceof Promise) {
433
+ g.then((y) => {
434
+ y === !1 ? (r.stopImmediatePropagation(), r.stopPropagation()) : this.executeMethod(d, r, u);
435
+ });
436
+ return;
437
+ } else if (g === !1) {
438
+ r.stopImmediatePropagation(), r.stopPropagation();
439
+ return;
440
+ }
441
+ }
442
+ this.executeMethod(d, r, u);
443
+ return;
444
+ }
445
+ }
446
+ }
447
+ if (a === this) break;
448
+ a = a.parentElement;
449
+ }
450
+ };
451
+ this.target.addEventListener("click", (r) => n(r, "@click")), this.target.addEventListener("input", (r) => n(r, "@input"));
452
+ }
453
+ static get observedAttributes() {
454
+ return Reflect.getMetadata("nf:inputs", i.prototype) || [];
455
+ }
456
+ attributeChangedCallback(s, n, r) {
457
+ r && /^\{[^{}]+\}$/.test(r) || n !== r && (this.proxy ? (this.proxy[s] = r, this.update()) : this.instance && (this.instance[s] = r));
458
+ }
459
+ executeMethod(s, n, r) {
460
+ if (r !== void 0) {
461
+ const o = r.split(",").map((a) => (a = a.trim(), a === "e" || a === "$event" ? n : a === "true" ? !0 : a === "false" ? !1 : !isNaN(Number(a)) && a !== "" ? Number(a) : a.startsWith("'") && a.endsWith("'") || a.startsWith('"') && a.endsWith('"') ? a.slice(1, -1) : a));
462
+ s.apply(this.proxy, o);
463
+ } else
464
+ s.call(this.proxy, n);
465
+ }
466
+ async connectedCallback() {
467
+ const s = Reflect.getMetadata("nf:canActivate", i);
468
+ if (s)
469
+ try {
470
+ const o = await s();
471
+ if (o === !1) return;
472
+ if (typeof o == "string") {
473
+ N.instance.navigate(o);
474
+ return;
475
+ }
476
+ } catch (o) {
477
+ console.error("Guard evaluation failed:", o);
478
+ return;
479
+ }
480
+ if (this.instance.canActivate)
481
+ try {
482
+ const o = await this.instance.canActivate.call(this.proxy);
483
+ if (o === !1) return;
484
+ if (typeof o == "string") {
485
+ N.instance.navigate(o);
486
+ return;
487
+ }
488
+ } catch (o) {
489
+ console.error("Lifecycle canActivate hook failed:", o);
490
+ return;
491
+ }
492
+ if (t.templateUrl) {
493
+ const o = await fetch(t.templateUrl);
494
+ this.instance.template = await o.text();
495
+ }
496
+ const n = Reflect.getMetadata("nf:params", i.prototype) || [];
497
+ if (n.length > 0) {
498
+ const o = N.instance;
499
+ this.routeUnsubscribe = o.onRouteMatch((a, c) => {
500
+ n.forEach((l) => {
501
+ c[l.paramName] !== void 0 && this.proxy[l.key] !== c[l.paramName] && (this.proxy[l.key] = c[l.paramName]);
502
+ });
503
+ });
504
+ }
505
+ (Reflect.getMetadata("nf:injects", i.prototype) || []).forEach((o) => {
506
+ let a = this.parentElement;
507
+ for (; a; ) {
508
+ if (a.instance) {
509
+ const l = (Reflect.getMetadata("nf:provides", a.instance.constructor) || []).find((f) => f.key === o.key);
510
+ if (l) {
511
+ this.proxy[o.property] = a.proxy[l.property];
512
+ break;
513
+ }
514
+ }
515
+ a = a.parentElement || a.getRootNode().host;
516
+ }
517
+ }), this.instance.onInit && await this.instance.onInit.call(this.proxy), this.update(), this.instance.onRender && this.instance.onRender.call(this.proxy, this);
518
+ }
519
+ disconnectedCallback() {
520
+ this.routeUnsubscribe && this.routeUnsubscribe(), this.instance.onDestroy && this.instance.onDestroy();
521
+ }
522
+ update() {
523
+ const s = this.instance.template || "<div>No template</div>", n = Reflect.getMetadata("nf:transforms", this.instance) || [], r = {};
524
+ for (const c of n)
525
+ typeof this.proxy[c] == "function" && (r[c] = this.proxy[c]);
526
+ const o = Object.create(this.proxy);
527
+ o.__transforms__ = r;
528
+ const a = D.render(s, o);
529
+ U(this.target, a);
530
+ }
531
+ }
532
+ );
533
+ }
534
+ const M = class M {
535
+ constructor() {
536
+ // ── State ─────────────────────────────────────────────────
537
+ h(this, "middlewares", []);
538
+ }
539
+ static get instance() {
540
+ return M._instance || (M._instance = new M()), M._instance;
541
+ }
542
+ // ── Public API ────────────────────────────────────────────
543
+ /** Register an error-handling middleware. Returns an unsubscribe function. */
544
+ addMiddleware(t) {
545
+ return this.middlewares.push(t), () => {
546
+ this.middlewares = this.middlewares.filter((e) => e !== t);
547
+ };
548
+ }
549
+ /**
550
+ * Run the middleware chain. The first middleware that returns `true`
551
+ * stops propagation. If no middleware handles it, logs to console.
552
+ */
553
+ handle(t) {
554
+ for (const e of this.middlewares)
555
+ if (e(t) === !0) return;
556
+ console.error("[JunoJS ErrorHandler] Unhandled error:", t.message, t);
557
+ }
558
+ /** Convenience: create a JunoJSError from an HTTP Response. */
559
+ static fromResponse(t, e) {
560
+ return {
561
+ status: t.status,
562
+ message: `HTTP ${t.status}: ${t.statusText}`,
563
+ url: e,
564
+ original: t
565
+ };
566
+ }
567
+ /** Convenience: create a JunoJSError from a caught exception. */
568
+ static fromException(t) {
569
+ return t instanceof Error ? { message: t.message, original: t } : { message: String(t), original: t };
570
+ }
571
+ };
572
+ // ── Singleton ─────────────────────────────────────────────
573
+ h(M, "_instance");
574
+ let S = M;
575
+ class ot {
576
+ constructor() {
577
+ h(this, "_initialValues", {});
578
+ h(this, "_touched", {});
579
+ queueMicrotask(() => this._captureInitialValues());
580
+ }
581
+ // ─── Public API ───────────────────────────────────────────
582
+ /** Returns true if every validated field passes all its rules. */
583
+ isValid() {
584
+ const t = this.getErrors();
585
+ return Object.keys(t).length === 0;
586
+ }
587
+ /** Returns a map of field → error messages (only fields with errors). */
588
+ getErrors() {
589
+ const t = Reflect.getMetadata("nf:validators", this) || /* @__PURE__ */ new Map(), e = {};
590
+ return t.forEach((s, n) => {
591
+ const r = this[n], o = [];
592
+ for (const a of s)
593
+ a.validate(r, this) || o.push(a.message);
594
+ o.length > 0 && (e[n] = o);
595
+ }), e;
596
+ }
597
+ /** Resets all fields to their initial values and clears touched state. */
598
+ reset() {
599
+ for (const [t, e] of Object.entries(this._initialValues))
600
+ this[t] = e;
601
+ this._touched = {};
602
+ }
603
+ /** True if any field differs from its initial value. */
604
+ get dirty() {
605
+ for (const [t, e] of Object.entries(this._initialValues))
606
+ if (this[t] !== e) return !0;
607
+ return !1;
608
+ }
609
+ /** Per-field touched tracking. */
610
+ get touched() {
611
+ return { ...this._touched };
612
+ }
613
+ /** Mark a field as touched (e.g. on blur). */
614
+ markTouched(t) {
615
+ this._touched[t] = !0;
616
+ }
617
+ // ─── Internals ────────────────────────────────────────────
618
+ _captureInitialValues() {
619
+ (Reflect.getMetadata("nf:validators", this) || /* @__PURE__ */ new Map()).forEach((e, s) => {
620
+ this._initialValues[s] = this[s];
621
+ });
622
+ }
623
+ }
624
+ function T(i, t, e) {
625
+ const s = Reflect.getMetadata("nf:validators", i) || /* @__PURE__ */ new Map(), n = s.get(t) || [];
626
+ n.push(e), s.set(t, n), Reflect.defineMetadata("nf:validators", s, i);
627
+ }
628
+ function ct(i = "This field is required") {
629
+ return (t, e) => {
630
+ T(t, e, {
631
+ name: "required",
632
+ message: i,
633
+ validate: (s) => s != null && String(s).trim().length > 0
634
+ });
635
+ };
636
+ }
637
+ function lt(i = "Invalid email address") {
638
+ return (t, e) => {
639
+ T(t, e, {
640
+ name: "email",
641
+ message: i,
642
+ validate: (s) => s ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(s)) : !0
643
+ });
644
+ };
645
+ }
646
+ function ft(i, t) {
647
+ return (e, s) => {
648
+ T(e, s, {
649
+ name: "match",
650
+ message: t || `Must match ${i}`,
651
+ validate: (n, r) => n === r[i]
652
+ });
653
+ };
654
+ }
655
+ function dt(i, t = "Invalid format") {
656
+ return (e, s) => {
657
+ T(e, s, {
658
+ name: "pattern",
659
+ message: t,
660
+ validate: (n) => n ? i.test(String(n)) : !0
661
+ });
662
+ };
663
+ }
664
+ class b {
665
+ constructor() {
666
+ h(this, "rules", []);
667
+ h(this, "IS_REQUIRED", !1);
668
+ }
669
+ required(t = "Required") {
670
+ return this.IS_REQUIRED = !0, this.rules.push((e) => !e && e !== 0 && e !== !1 ? t : void 0), this;
671
+ }
672
+ email(t = "Invalid email") {
673
+ return this.rules.push((e) => {
674
+ if (e)
675
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(e)) ? void 0 : t;
676
+ }), this;
677
+ }
678
+ min(t, e) {
679
+ return this.rules.push((s) => {
680
+ if (s)
681
+ return String(s).length < t ? e || `Min length ${t}` : void 0;
682
+ }), this;
683
+ }
684
+ max(t, e) {
685
+ return this.rules.push((s) => {
686
+ if (s)
687
+ return String(s).length > t ? e || `Max length ${t}` : void 0;
688
+ }), this;
689
+ }
690
+ validate(t, e) {
691
+ for (const s of this.rules) {
692
+ const n = s(t, e);
693
+ if (n) return n;
694
+ }
695
+ }
696
+ }
697
+ class V {
698
+ constructor() {
699
+ h(this, "fields", {});
700
+ h(this, "refines", []);
701
+ }
702
+ string() {
703
+ return new b();
704
+ }
705
+ number() {
706
+ return new b();
707
+ }
708
+ boolean() {
709
+ return new b();
710
+ }
711
+ shape(t) {
712
+ return this.fields = t, this;
713
+ }
714
+ refine(t, e) {
715
+ return this.refines.push({ validate: t, ...e }), this;
716
+ }
717
+ async parse(t) {
718
+ const e = {};
719
+ let s = !0;
720
+ for (const [n, r] of Object.entries(this.fields)) {
721
+ const o = r.validate(t[n], t);
722
+ o && (e[n] = o, s = !1);
723
+ }
724
+ for (const n of this.refines) {
725
+ const r = n.validate(t);
726
+ (r instanceof Promise ? await r : r) || (e[n.path] = n.message, s = !1);
727
+ }
728
+ return { success: s, errors: s ? void 0 : e };
729
+ }
730
+ }
731
+ const ut = {
732
+ string: () => new b(),
733
+ number: () => new b(),
734
+ boolean: () => new b(),
735
+ object: (i) => new V().shape(i)
736
+ };
737
+ class ht {
738
+ constructor() {
739
+ h(this, "requestInterceptors", []);
740
+ h(this, "responseInterceptors", []);
741
+ h(this, "errorHandler", null);
742
+ }
743
+ /** Plug in the global ErrorHandler for automatic error routing. */
744
+ setErrorHandler(t) {
745
+ this.errorHandler = t;
746
+ }
747
+ // ── Interceptors ──────────────────────────────────────────
748
+ addRequestInterceptor(t) {
749
+ this.requestInterceptors.push(t);
750
+ }
751
+ addResponseInterceptor(t) {
752
+ this.responseInterceptors.push(t);
753
+ }
754
+ // ── HTTP Methods ──────────────────────────────────────────
755
+ async get(t, e) {
756
+ return this.request("GET", t, void 0, e);
757
+ }
758
+ async post(t, e, s) {
759
+ return this.request("POST", t, e, s);
760
+ }
761
+ async put(t, e, s) {
762
+ return this.request("PUT", t, e, s);
763
+ }
764
+ async delete(t, e) {
765
+ return this.request("DELETE", t, void 0, e);
766
+ }
767
+ async patch(t, e, s) {
768
+ return this.request("PATCH", t, e, s);
769
+ }
770
+ // ── Core ──────────────────────────────────────────────────
771
+ async request(t, e, s, n) {
772
+ let r = e;
773
+ if (n != null && n.params) {
774
+ const f = new URLSearchParams(n.params).toString();
775
+ r += (e.includes("?") ? "&" : "?") + f;
776
+ }
777
+ const o = {
778
+ "Content-Type": "application/json",
779
+ ...(n == null ? void 0 : n.headers) || {}
780
+ }, a = { method: t, headers: o };
781
+ s !== void 0 && (a.body = JSON.stringify(s));
782
+ const c = new AbortController();
783
+ let l;
784
+ n != null && n.signal && n.signal.addEventListener("abort", () => c.abort()), n != null && n.timeout && n.timeout > 0 && (l = setTimeout(() => c.abort(), n.timeout)), a.signal = c.signal;
785
+ for (const f of this.requestInterceptors) {
786
+ const p = f(r, a);
787
+ p && ([r] = p, Object.assign(a, p[1]));
788
+ }
789
+ try {
790
+ let f = await fetch(r, a);
791
+ for (const u of this.responseInterceptors) {
792
+ const d = u(f);
793
+ d && (f = d);
794
+ }
795
+ if (!f.ok)
796
+ throw this.errorHandler && this.errorHandler.handle(
797
+ S.fromResponse(f, r)
798
+ ), new Error(`HTTP ${f.status}: ${f.statusText}`);
799
+ return (f.headers.get("content-type") || "").includes("application/json") ? await f.json() : await f.text();
800
+ } finally {
801
+ l !== void 0 && clearTimeout(l);
802
+ }
803
+ }
804
+ }
805
+ const R = class R {
806
+ constructor() {
807
+ // ── State ─────────────────────────────────────────────────
808
+ h(this, "dictionaries", /* @__PURE__ */ new Map());
809
+ h(this, "_locale", "en");
810
+ h(this, "_onLocaleChange", []);
811
+ }
812
+ static get instance() {
813
+ return R._instance || (R._instance = new R()), R._instance;
814
+ }
815
+ /** Current active locale. */
816
+ get locale() {
817
+ return this._locale;
818
+ }
819
+ // ── Public API ────────────────────────────────────────────
820
+ /** Register translations for a locale. Merges with any existing entries. */
821
+ addTranslations(t, e) {
822
+ const s = this.dictionaries.get(t) || {};
823
+ this.dictionaries.set(t, { ...s, ...e });
824
+ }
825
+ /** Switch the active locale. */
826
+ setLocale(t) {
827
+ this.dictionaries.has(t) || console.warn(`[i18n] No translations registered for locale "${t}".`), this._locale = t;
828
+ for (const e of this._onLocaleChange) e();
829
+ }
830
+ /** Subscribe to locale changes. Returns an unsubscribe function. */
831
+ onLocaleChange(t) {
832
+ return this._onLocaleChange.push(t), () => {
833
+ this._onLocaleChange = this._onLocaleChange.filter((e) => e !== t);
834
+ };
835
+ }
836
+ /**
837
+ * Translate a key with optional parameter interpolation.
838
+ * Params replace `{{paramName}}` placeholders in the translation string.
839
+ *
840
+ * t('greeting', { name: 'Ada' }) // "Hello, Ada!"
841
+ */
842
+ t(t, e) {
843
+ const s = this.dictionaries.get(this._locale);
844
+ let n = s == null ? void 0 : s[t];
845
+ if (n === void 0)
846
+ return t;
847
+ if (e)
848
+ for (const [r, o] of Object.entries(e))
849
+ n = n.replace(
850
+ new RegExp(`\\{\\{${r}\\}\\}`, "g"),
851
+ String(o)
852
+ );
853
+ return n;
854
+ }
855
+ /** List all registered locales. */
856
+ get availableLocales() {
857
+ return [...this.dictionaries.keys()];
858
+ }
859
+ };
860
+ // ── Singleton ─────────────────────────────────────────────
861
+ h(R, "_instance");
862
+ let _ = R;
863
+ export {
864
+ X as Action,
865
+ st as CanActivate,
866
+ J as Component,
867
+ lt as Email,
868
+ S as ErrorHandler,
869
+ ot as FormModel,
870
+ V as FormSchema,
871
+ nt as HostElement,
872
+ ht as HttpClient,
873
+ _ as I18nService,
874
+ Y as Inject,
875
+ K as Input,
876
+ et as Intercept,
877
+ D as JunoEngine,
878
+ ft as Match,
879
+ z as Param,
880
+ dt as Pattern,
881
+ rt as Persist,
882
+ B as Provide,
883
+ Z as Refine,
884
+ ct as Required,
885
+ N as RouterService,
886
+ it as Schema,
887
+ b as SchemaField,
888
+ W as State,
889
+ Q as Transform,
890
+ G as Use,
891
+ tt as Validate,
892
+ at as bootstrap,
893
+ q as createReactiveProxy,
894
+ ut as s
895
+ };
896
+ //# sourceMappingURL=index.js.map