frontend-auto-cms 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime/dashboard.js +152 -124
- package/package.json +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
const xe = "cms-export.patch.json", ve = "frontend-auto-cms::content",
|
|
2
|
-
function
|
|
1
|
+
const xe = "cms-export.patch.json", ve = "frontend-auto-cms::content", ne = "frontend-auto-cms::locales";
|
|
2
|
+
function oe(e) {
|
|
3
3
|
localStorage.setItem(ve, JSON.stringify(e));
|
|
4
4
|
}
|
|
5
|
-
function
|
|
5
|
+
function re() {
|
|
6
6
|
try {
|
|
7
|
-
const e = localStorage.getItem(
|
|
7
|
+
const e = localStorage.getItem(ne);
|
|
8
8
|
return e ? JSON.parse(e) : {};
|
|
9
9
|
} catch {
|
|
10
10
|
return {};
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
function I(e) {
|
|
14
|
-
localStorage.setItem(
|
|
14
|
+
localStorage.setItem(ne, JSON.stringify(e));
|
|
15
15
|
}
|
|
16
16
|
async function ke() {
|
|
17
17
|
try {
|
|
@@ -24,7 +24,7 @@ async function ke() {
|
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
async function
|
|
27
|
+
async function se() {
|
|
28
28
|
try {
|
|
29
29
|
const e = await fetch("/cms-locales.json", { cache: "no-store" });
|
|
30
30
|
if (!e.ok)
|
|
@@ -60,7 +60,7 @@ function v(e) {
|
|
|
60
60
|
const a = (e.getAttribute("class") ?? "").split(/\s+/).filter(Boolean)[0];
|
|
61
61
|
return a ? `${e.tagName.toLowerCase()}.${a}` : e.tagName.toLowerCase();
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function ie(e) {
|
|
64
64
|
return ["SCRIPT", "STYLE", "NOSCRIPT", "IFRAME"].includes(e.tagName);
|
|
65
65
|
}
|
|
66
66
|
function N(e) {
|
|
@@ -68,7 +68,7 @@ function N(e) {
|
|
|
68
68
|
}
|
|
69
69
|
function $e(e, t, a) {
|
|
70
70
|
const o = t.parentElement;
|
|
71
|
-
if (!o ||
|
|
71
|
+
if (!o || ie(o))
|
|
72
72
|
return null;
|
|
73
73
|
if (Array.from(o.childNodes).filter(
|
|
74
74
|
(s) => s.nodeType === Node.TEXT_NODE && N(s.nodeValue).length > 0
|
|
@@ -95,12 +95,12 @@ function S(e = document, t) {
|
|
|
95
95
|
if (m.length < 2)
|
|
96
96
|
continue;
|
|
97
97
|
o += 1;
|
|
98
|
-
const
|
|
98
|
+
const J = `${A(i || "index")}.text.${o}`, O = $e(e, b, J);
|
|
99
99
|
if (!O)
|
|
100
100
|
continue;
|
|
101
101
|
a.push({
|
|
102
102
|
id: `dom_txt_${o}`,
|
|
103
|
-
key:
|
|
103
|
+
key: J,
|
|
104
104
|
type: "text",
|
|
105
105
|
label: v(O),
|
|
106
106
|
value: m,
|
|
@@ -110,7 +110,7 @@ function S(e = document, t) {
|
|
|
110
110
|
continue;
|
|
111
111
|
}
|
|
112
112
|
const l = d;
|
|
113
|
-
if (
|
|
113
|
+
if (ie(l))
|
|
114
114
|
continue;
|
|
115
115
|
const p = l.tagName.toLowerCase();
|
|
116
116
|
if (p === "img" || p === "video") {
|
|
@@ -172,7 +172,7 @@ function S(e = document, t) {
|
|
|
172
172
|
nodes: a
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
|
-
function
|
|
175
|
+
function P(e, t = document) {
|
|
176
176
|
if (!e.key)
|
|
177
177
|
return;
|
|
178
178
|
const a = t.querySelector(`[data-cms-key="${CSS.escape(e.key)}"]`);
|
|
@@ -256,15 +256,15 @@ const B = [
|
|
|
256
256
|
{ code: "uz", label: "Uzbek", nllb: "uzn_Latn" },
|
|
257
257
|
{ code: "vi", label: "Vietnamese", nllb: "vie_Latn" },
|
|
258
258
|
{ code: "zh", label: "Chinese (Simplified)", nllb: "zho_Hans" }
|
|
259
|
-
],
|
|
259
|
+
], W = Object.fromEntries(
|
|
260
260
|
B.map((e) => [e.nllb.slice(0, 3).toLowerCase(), e.code])
|
|
261
261
|
), Se = "https://api.mymemory.translated.net/get";
|
|
262
|
-
function
|
|
262
|
+
function Y(e) {
|
|
263
263
|
const t = e.trim().toLowerCase().split(/[-_]/)[0];
|
|
264
264
|
if (/^[a-z]{2}$/i.test(t))
|
|
265
265
|
return t;
|
|
266
|
-
if (/^[a-z]{3}$/i.test(t) &&
|
|
267
|
-
return
|
|
266
|
+
if (/^[a-z]{3}$/i.test(t) && W[t])
|
|
267
|
+
return W[t];
|
|
268
268
|
throw new Error(`Unsupported language code "${e}" for MyMemory translation.`);
|
|
269
269
|
}
|
|
270
270
|
async function Ee(e, t, a) {
|
|
@@ -283,7 +283,7 @@ async function Ee(e, t, a) {
|
|
|
283
283
|
return typeof s == "string" && s.trim() ? s : e;
|
|
284
284
|
}
|
|
285
285
|
async function _e(e, t, a = "en", o) {
|
|
286
|
-
const n =
|
|
286
|
+
const n = Y(a), r = Y(t), s = /* @__PURE__ */ new Map(), i = {}, c = Object.entries(e), u = c.length;
|
|
287
287
|
let d = 0;
|
|
288
288
|
for (const [l, p] of c) {
|
|
289
289
|
if (s.has(p)) {
|
|
@@ -300,10 +300,10 @@ async function _e(e, t, a = "en", o) {
|
|
|
300
300
|
}
|
|
301
301
|
return i;
|
|
302
302
|
}
|
|
303
|
-
function
|
|
303
|
+
function le(e) {
|
|
304
304
|
return /^[^/\s]+\/[^/\s]+$/.test(e);
|
|
305
305
|
}
|
|
306
|
-
function
|
|
306
|
+
function ce(e) {
|
|
307
307
|
return /^([^/\s]+\/)+[^/\s]+$/.test(e);
|
|
308
308
|
}
|
|
309
309
|
async function Ae(e, t, a) {
|
|
@@ -324,7 +324,7 @@ async function Te() {
|
|
|
324
324
|
if (!t || !t.provider || t.provider === "none" || t.provider !== "github" && t.provider !== "gitlab" || typeof t.repository != "string" || !t.repository.trim())
|
|
325
325
|
return null;
|
|
326
326
|
const a = t.repository.trim();
|
|
327
|
-
return t.provider === "github" && !
|
|
327
|
+
return t.provider === "github" && !le(a) || t.provider === "gitlab" && !ce(a) || typeof t.branch != "string" || !t.branch.trim() ? null : { ...t, repository: a, branch: t.branch.trim() };
|
|
328
328
|
} catch {
|
|
329
329
|
return null;
|
|
330
330
|
}
|
|
@@ -385,28 +385,36 @@ async function Oe(e, t, a) {
|
|
|
385
385
|
}
|
|
386
386
|
async function ze(e, t, a, o) {
|
|
387
387
|
const n = /* @__PURE__ */ new Map();
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
388
|
+
let r = 0;
|
|
389
|
+
a.forEach((i) => {
|
|
390
|
+
i.find !== i.replace && (r += 1);
|
|
391
|
+
const c = Ce(i.file);
|
|
392
|
+
if (!c)
|
|
391
393
|
return;
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
+
const u = n.get(c) ?? [];
|
|
395
|
+
u.push({ ...i, file: c }), n.set(c, u);
|
|
394
396
|
});
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
397
|
+
let s = 0;
|
|
398
|
+
for (const [i, c] of n.entries()) {
|
|
399
|
+
const u = await Oe(e, t, i);
|
|
400
|
+
if (!u)
|
|
398
401
|
continue;
|
|
399
|
-
let
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}),
|
|
402
|
+
let d = u.content;
|
|
403
|
+
c.forEach((l) => {
|
|
404
|
+
d = Ie(d, l.find, l.replace, l.occurrence ?? 1);
|
|
405
|
+
}), d !== u.content && (await $(e, t, i, d, o), s += 1);
|
|
403
406
|
}
|
|
407
|
+
return { updatedFiles: s, attemptedFiles: n.size, actionableOperations: r };
|
|
404
408
|
}
|
|
405
409
|
async function Ne(e, t, a) {
|
|
406
|
-
const o = `chore(cms): publish content updates ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
407
|
-
if (
|
|
408
|
-
|
|
409
|
-
|
|
410
|
+
const o = `chore(cms): publish content updates ${(/* @__PURE__ */ new Date()).toISOString()}`, n = await ze(e, t, a.operations ?? [], o);
|
|
411
|
+
if (n.actionableOperations > 0 && n.updatedFiles === 0)
|
|
412
|
+
throw new Error(
|
|
413
|
+
`No source files were updated (${n.attemptedFiles} candidate files checked). Run setup again to refresh cms-route-map.json and retry.`
|
|
414
|
+
);
|
|
415
|
+
if (await $(e, t, "cms-content.json", JSON.stringify(a.content, null, 2), o), a.locales) {
|
|
416
|
+
for (const [r, s] of Object.entries(a.locales))
|
|
417
|
+
await $(e, t, `locales/${r}.json`, JSON.stringify(s, null, 2), o);
|
|
410
418
|
await $(
|
|
411
419
|
e,
|
|
412
420
|
t,
|
|
@@ -450,18 +458,18 @@ async function Me(e, t, a) {
|
|
|
450
458
|
})).ok)
|
|
451
459
|
throw new Error("GitLab publish failed.");
|
|
452
460
|
}
|
|
453
|
-
async function
|
|
461
|
+
async function Re(e, t, a) {
|
|
454
462
|
if (!a || !t.trim())
|
|
455
463
|
return !1;
|
|
456
|
-
if (a.provider === "github" && !
|
|
464
|
+
if (a.provider === "github" && !le(a.repository))
|
|
457
465
|
throw new Error('Invalid GitHub repository format. Use "owner/repo".');
|
|
458
|
-
if (a.provider === "gitlab" && !
|
|
466
|
+
if (a.provider === "gitlab" && !ce(a.repository))
|
|
459
467
|
throw new Error('Invalid GitLab repository format. Use "group/project".');
|
|
460
468
|
return a.provider === "github" ? (await Ne(a, t.trim(), e), !0) : a.provider === "gitlab" ? (await Me(a, t.trim(), e), !0) : !1;
|
|
461
469
|
}
|
|
462
|
-
const
|
|
463
|
-
let D = !1, k = null,
|
|
464
|
-
function
|
|
470
|
+
const V = "facms-auth-modal", M = "facms-auth-missing", X = "facms-token-modal", Z = "facms-language-modal", Pe = "frontend-auto-cms::theme", de = "frontend-auto-cms::main-language", ue = "frontend-auto-cms::language-labels";
|
|
471
|
+
let D = !1, k = null, Q = !1, x = null, f = "dark", U = {};
|
|
472
|
+
function fe() {
|
|
465
473
|
if (document.getElementById("facms-dashboard-css"))
|
|
466
474
|
return;
|
|
467
475
|
const e = document.createElement("style");
|
|
@@ -700,15 +708,15 @@ function ue() {
|
|
|
700
708
|
}
|
|
701
709
|
`, document.head.appendChild(e);
|
|
702
710
|
}
|
|
703
|
-
function
|
|
711
|
+
function pe(e) {
|
|
704
712
|
f = e;
|
|
705
713
|
const t = e === "dark";
|
|
706
|
-
document.documentElement.classList.toggle("dark", t), document.body.classList.toggle("dark", t), document.documentElement.style.background = t ? "#020617" : "#f1f5f9", document.body.style.background = t ? "#020617" : "#f1f5f9", document.documentElement.setAttribute("data-facms-theme", e), document.getElementById("facms-app")?.classList.toggle("dark", t), localStorage.setItem(
|
|
714
|
+
document.documentElement.classList.toggle("dark", t), document.body.classList.toggle("dark", t), document.documentElement.style.background = t ? "#020617" : "#f1f5f9", document.body.style.background = t ? "#020617" : "#f1f5f9", document.documentElement.setAttribute("data-facms-theme", e), document.getElementById("facms-app")?.classList.toggle("dark", t), localStorage.setItem(Pe, e);
|
|
707
715
|
const o = document.getElementById("facms-theme-toggle");
|
|
708
716
|
o && (o.textContent = e === "dark" ? "Switch to light" : "Switch to dark");
|
|
709
717
|
}
|
|
710
|
-
function
|
|
711
|
-
f = "dark",
|
|
718
|
+
function ge() {
|
|
719
|
+
f = "dark", pe("dark");
|
|
712
720
|
}
|
|
713
721
|
function Be(e) {
|
|
714
722
|
return Array.from(new Uint8Array(e)).map((t) => t.toString(16).padStart(2, "0")).join("");
|
|
@@ -717,7 +725,7 @@ async function De(e) {
|
|
|
717
725
|
const t = new TextEncoder().encode(e), a = await crypto.subtle.digest("SHA-256", t);
|
|
718
726
|
return Be(a);
|
|
719
727
|
}
|
|
720
|
-
async function
|
|
728
|
+
async function be() {
|
|
721
729
|
if (x)
|
|
722
730
|
return x;
|
|
723
731
|
try {
|
|
@@ -726,7 +734,7 @@ async function ge() {
|
|
|
726
734
|
const t = await e.json();
|
|
727
735
|
return x = {
|
|
728
736
|
dashboardPath: t.dashboardPath || "/dashboard",
|
|
729
|
-
pages: (t.pages?.length ? t.pages : ["/"]).map((a) =>
|
|
737
|
+
pages: (t.pages?.length ? t.pages : ["/"]).map((a) => H(a)),
|
|
730
738
|
showFloatingButton: t.showFloatingButton ?? !1,
|
|
731
739
|
autoTranslateEnabled: t.autoTranslateEnabled ?? !0
|
|
732
740
|
}, x;
|
|
@@ -735,9 +743,9 @@ async function ge() {
|
|
|
735
743
|
}
|
|
736
744
|
return x = { dashboardPath: "/dashboard", pages: ["/"], showFloatingButton: !1, autoTranslateEnabled: !0 }, x;
|
|
737
745
|
}
|
|
738
|
-
async function
|
|
739
|
-
if (!
|
|
740
|
-
|
|
746
|
+
async function G() {
|
|
747
|
+
if (!Q) {
|
|
748
|
+
Q = !0;
|
|
741
749
|
try {
|
|
742
750
|
const e = await fetch("/cms-runtime-auth.json", { cache: "no-store" });
|
|
743
751
|
if (!e.ok) return;
|
|
@@ -750,7 +758,7 @@ async function U() {
|
|
|
750
758
|
}
|
|
751
759
|
async function Ue(e) {
|
|
752
760
|
const t = e.trim();
|
|
753
|
-
return !t || (await
|
|
761
|
+
return !t || (await G(), !k) ? !1 : await De(`${k.salt}:${t}`) === k.passcodeHash;
|
|
754
762
|
}
|
|
755
763
|
function Ge() {
|
|
756
764
|
let e = document.getElementById(M);
|
|
@@ -765,17 +773,17 @@ function Ge() {
|
|
|
765
773
|
function He() {
|
|
766
774
|
document.getElementById(M)?.remove();
|
|
767
775
|
}
|
|
768
|
-
async function
|
|
769
|
-
return await
|
|
776
|
+
async function me() {
|
|
777
|
+
return await G(), k ? (He(), !0) : (Ge(), !1);
|
|
770
778
|
}
|
|
771
|
-
function
|
|
772
|
-
const t = document.getElementById(
|
|
779
|
+
function he(e) {
|
|
780
|
+
const t = document.getElementById(V);
|
|
773
781
|
if (t) {
|
|
774
782
|
t.style.display = "grid";
|
|
775
783
|
return;
|
|
776
784
|
}
|
|
777
785
|
const a = document.createElement("div");
|
|
778
|
-
a.id =
|
|
786
|
+
a.id = V, a.style.position = "fixed", a.style.inset = "0", a.style.zIndex = "2147483647", a.style.background = "rgba(2, 6, 23, 0.45)", a.style.display = "grid", a.style.placeItems = "center", a.innerHTML = `
|
|
779
787
|
<div style="width: min(420px, 92vw); background: ${f === "dark" ? "#0f172a" : "#ffffff"}; color: ${f === "dark" ? "#e2e8f0" : "#0f172a"}; border: 1px solid ${f === "dark" ? "#334155" : "#e2e8f0"}; border-radius: 16px; padding: 16px; box-shadow: 0 20px 55px rgba(2,6,23,0.45); font-family: Inter, system-ui, sans-serif;">
|
|
780
788
|
<h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Unlock CMS</h3>
|
|
781
789
|
<p style="margin: 0 0 12px 0; font-size: 12px; color: ${f === "dark" ? "#94a3b8" : "#475569"};">Enter your passcode to edit content.</p>
|
|
@@ -788,7 +796,7 @@ function me(e) {
|
|
|
788
796
|
</div>
|
|
789
797
|
`;
|
|
790
798
|
const o = a.querySelector("#facms-passcode-input"), n = a.querySelector("#facms-passcode-error"), r = () => a.style.display = "none", s = async () => {
|
|
791
|
-
if (await
|
|
799
|
+
if (await G(), !k) {
|
|
792
800
|
n && (n.textContent = "CMS auth is not configured. Run setup to generate runtime auth files.", n.style.display = "block");
|
|
793
801
|
return;
|
|
794
802
|
}
|
|
@@ -801,10 +809,10 @@ function me(e) {
|
|
|
801
809
|
a.querySelector("#facms-passcode-cancel")?.addEventListener("click", r), a.querySelector("#facms-passcode-submit")?.addEventListener("click", s), o?.addEventListener("keydown", (i) => i.key === "Enter" && void s()), document.body.appendChild(a), o?.focus();
|
|
802
810
|
}
|
|
803
811
|
function qe(e, t) {
|
|
804
|
-
const a = document.getElementById(
|
|
812
|
+
const a = document.getElementById(X);
|
|
805
813
|
a && a.remove();
|
|
806
814
|
const o = document.createElement("div");
|
|
807
|
-
o.id =
|
|
815
|
+
o.id = X, o.style.position = "fixed", o.style.inset = "0", o.style.zIndex = "2147483647", o.style.background = "rgba(2, 6, 23, 0.45)", o.style.display = "grid", o.style.placeItems = "center", o.innerHTML = `
|
|
808
816
|
<div style="width: min(520px, 92vw); background: ${f === "dark" ? "#0f172a" : "#ffffff"}; color: ${f === "dark" ? "#e2e8f0" : "#0f172a"}; border: 1px solid ${f === "dark" ? "#334155" : "#e2e8f0"}; border-radius: 16px; padding: 16px; box-shadow: 0 20px 55px rgba(2,6,23,0.45); font-family: Inter, system-ui, sans-serif;">
|
|
809
817
|
<h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Publish token required</h3>
|
|
810
818
|
<p style="margin: 0 0 12px 0; font-size: 12px; color: ${f === "dark" ? "#94a3b8" : "#475569"};">Enter your ${e} token for this publish only. It is not stored.</p>
|
|
@@ -827,10 +835,10 @@ function qe(e, t) {
|
|
|
827
835
|
o.querySelector("#facms-token-cancel")?.addEventListener("click", s), o.querySelector("#facms-token-submit")?.addEventListener("click", i), n?.addEventListener("keydown", (c) => c.key === "Enter" && i()), document.body.appendChild(o), n?.focus();
|
|
828
836
|
}
|
|
829
837
|
function Ke(e, t, a) {
|
|
830
|
-
const o = document.getElementById(
|
|
838
|
+
const o = document.getElementById(Z);
|
|
831
839
|
o && o.remove();
|
|
832
840
|
const n = document.createElement("div");
|
|
833
|
-
n.id =
|
|
841
|
+
n.id = Z, n.style.position = "fixed", n.style.inset = "0", n.style.zIndex = "2147483647", n.style.background = "rgba(2, 6, 23, 0.45)", n.style.display = "grid", n.style.placeItems = "center", n.innerHTML = `
|
|
834
842
|
<div style="width: min(520px, 92vw); background: ${f === "dark" ? "#0f172a" : "#ffffff"}; color: ${f === "dark" ? "#e2e8f0" : "#0f172a"}; border: 1px solid ${f === "dark" ? "#334155" : "#e2e8f0"}; border-radius: 16px; padding: 16px; box-shadow: 0 20px 55px rgba(2,6,23,0.45); font-family: Inter, system-ui, sans-serif;">
|
|
835
843
|
<h3 style="margin: 0 0 6px 0; font-size: 20px; line-height: 1.2; font-weight: 700;">Add translation</h3>
|
|
836
844
|
<p style="margin: 0 0 8px 0; font-size: 12px; color: ${f === "dark" ? "#94a3b8" : "#475569"};">Pick a supported language or define a custom one for manual translation.</p>
|
|
@@ -883,7 +891,7 @@ function z(e, t) {
|
|
|
883
891
|
function C(e) {
|
|
884
892
|
return e.trim().toLowerCase();
|
|
885
893
|
}
|
|
886
|
-
function
|
|
894
|
+
function H(e) {
|
|
887
895
|
const t = e.trim() || "/";
|
|
888
896
|
return t === "/" ? "/" : (t.startsWith("/") ? t : `/${t}`).toLowerCase();
|
|
889
897
|
}
|
|
@@ -891,9 +899,9 @@ function E(e) {
|
|
|
891
899
|
const t = C(e), a = B.find((o) => o.code === t);
|
|
892
900
|
return a ? a.label : t.toUpperCase();
|
|
893
901
|
}
|
|
894
|
-
function
|
|
902
|
+
function Fe() {
|
|
895
903
|
try {
|
|
896
|
-
const e = localStorage.getItem(
|
|
904
|
+
const e = localStorage.getItem(ue);
|
|
897
905
|
if (!e)
|
|
898
906
|
return {};
|
|
899
907
|
const t = JSON.parse(e);
|
|
@@ -902,15 +910,15 @@ function Je() {
|
|
|
902
910
|
return {};
|
|
903
911
|
}
|
|
904
912
|
}
|
|
905
|
-
function
|
|
906
|
-
localStorage.setItem(
|
|
913
|
+
function q(e) {
|
|
914
|
+
localStorage.setItem(ue, JSON.stringify(e));
|
|
907
915
|
}
|
|
908
916
|
function j(e) {
|
|
909
|
-
const t = localStorage.getItem(
|
|
917
|
+
const t = localStorage.getItem(de);
|
|
910
918
|
return t && e[t] ? t : e.en ? "en" : Object.keys(e)[0] ?? "en";
|
|
911
919
|
}
|
|
912
|
-
function
|
|
913
|
-
localStorage.setItem(
|
|
920
|
+
function ee(e) {
|
|
921
|
+
localStorage.setItem(de, e);
|
|
914
922
|
}
|
|
915
923
|
function h(e) {
|
|
916
924
|
return e.replace(/[&<>'"]/g, (t) => ({ "&": "&", "<": "<", ">": ">", "'": "'", '"': """ })[t]);
|
|
@@ -919,7 +927,7 @@ function T(e, t = 72) {
|
|
|
919
927
|
const a = e.replace(/\s+/g, " ").trim();
|
|
920
928
|
return a.length <= t ? a : `${a.slice(0, t)}...`;
|
|
921
929
|
}
|
|
922
|
-
function
|
|
930
|
+
function Je(e) {
|
|
923
931
|
return e.type === "section" ? T((e.sectionItems ?? []).join(" | ")) : e.type === "property" ? T(JSON.stringify(e.attrs ?? {})) : T(e.value);
|
|
924
932
|
}
|
|
925
933
|
function We(e) {
|
|
@@ -958,30 +966,43 @@ function Xe(e) {
|
|
|
958
966
|
if (!t)
|
|
959
967
|
return t;
|
|
960
968
|
if (t.startsWith("/")) {
|
|
961
|
-
const a =
|
|
962
|
-
return
|
|
969
|
+
const a = H(t);
|
|
970
|
+
return U[a] ?? t;
|
|
963
971
|
}
|
|
964
972
|
return t.replace(/^\.?\//, "");
|
|
965
973
|
}
|
|
966
974
|
async function Ze(e, t, a) {
|
|
967
|
-
const o = e.nodes.flatMap(
|
|
968
|
-
(
|
|
969
|
-
file:
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
975
|
+
const o = /* @__PURE__ */ new Set(), n = e.nodes.flatMap(
|
|
976
|
+
(i) => i.sourceRefs.map((c) => ({
|
|
977
|
+
file: (() => {
|
|
978
|
+
const u = (c.file ?? "").trim();
|
|
979
|
+
if (u.startsWith("/")) {
|
|
980
|
+
const d = H(u);
|
|
981
|
+
if (!U[d])
|
|
982
|
+
return o.add(d), u;
|
|
983
|
+
}
|
|
984
|
+
return Xe(u);
|
|
985
|
+
})(),
|
|
986
|
+
find: c.original,
|
|
987
|
+
replace: i.type === "property" ? JSON.stringify(i.attrs ?? {}) : i.type === "section" ? (i.sectionItems ?? []).join(" ") : (i.type === "text", i.value),
|
|
988
|
+
occurrence: c.occurrence ?? 1
|
|
973
989
|
}))
|
|
974
|
-
)
|
|
990
|
+
);
|
|
991
|
+
if (o.size)
|
|
992
|
+
throw new Error(
|
|
993
|
+
`Missing route mappings for: ${Array.from(o).join(", ")}. Run setup again and commit public/cms-route-map.json.`
|
|
994
|
+
);
|
|
995
|
+
const r = {
|
|
975
996
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
976
997
|
content: { ...e, updatedAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
977
|
-
operations:
|
|
998
|
+
operations: n,
|
|
978
999
|
locales: t
|
|
979
|
-
},
|
|
1000
|
+
}, s = await Ve(Ye(r));
|
|
980
1001
|
return {
|
|
981
|
-
...
|
|
1002
|
+
...r,
|
|
982
1003
|
integrity: {
|
|
983
1004
|
algorithm: "sha256",
|
|
984
|
-
value:
|
|
1005
|
+
value: s
|
|
985
1006
|
}
|
|
986
1007
|
};
|
|
987
1008
|
}
|
|
@@ -1000,7 +1021,7 @@ function Qe(e, t) {
|
|
|
1000
1021
|
}
|
|
1001
1022
|
function _(e, t, a, o) {
|
|
1002
1023
|
e.nodes.forEach((n) => {
|
|
1003
|
-
n.type === "text" && (n.value = t[n.key] ?? o[n.key] ?? n.value,
|
|
1024
|
+
n.type === "text" && (n.value = t[n.key] ?? o[n.key] ?? n.value, P(n, a));
|
|
1004
1025
|
});
|
|
1005
1026
|
}
|
|
1006
1027
|
function et(e, t) {
|
|
@@ -1029,7 +1050,7 @@ function tt(e, t) {
|
|
|
1029
1050
|
n.addEventListener("click", (r) => {
|
|
1030
1051
|
r.stopPropagation();
|
|
1031
1052
|
const s = n.dataset.mainLang;
|
|
1032
|
-
!s || !t.locales[s] || (t.mainLanguage = s,
|
|
1053
|
+
!s || !t.locales[s] || (t.mainLanguage = s, ee(s), t.baseTextByKey = { ...t.locales[s] }, L(e, t));
|
|
1033
1054
|
});
|
|
1034
1055
|
}), a.querySelectorAll("[data-remove-lang]").forEach((n) => {
|
|
1035
1056
|
n.addEventListener("click", (r) => {
|
|
@@ -1040,7 +1061,7 @@ function tt(e, t) {
|
|
|
1040
1061
|
alert("You must keep at least one language.");
|
|
1041
1062
|
return;
|
|
1042
1063
|
}
|
|
1043
|
-
delete t.locales[s], delete t.languageLabels[s],
|
|
1064
|
+
delete t.locales[s], delete t.languageLabels[s], q(t.languageLabels), I(t.locales), t.mainLanguage === s && (t.mainLanguage = j(t.locales), ee(t.mainLanguage), t.baseTextByKey = { ...t.locales[t.mainLanguage] ?? {} }), t.activeLanguage === s && (t.activeLanguage = K(t.locales, t.mainLanguage)), ye(t), L(e, t);
|
|
1044
1065
|
}
|
|
1045
1066
|
});
|
|
1046
1067
|
});
|
|
@@ -1065,22 +1086,22 @@ function at(e, t) {
|
|
|
1065
1086
|
} catch {
|
|
1066
1087
|
return;
|
|
1067
1088
|
}
|
|
1068
|
-
|
|
1089
|
+
P(r, t.workingDocument), oe(t.content);
|
|
1069
1090
|
}
|
|
1070
1091
|
});
|
|
1071
1092
|
});
|
|
1072
1093
|
}
|
|
1073
1094
|
function w(e, t, a) {
|
|
1074
1095
|
const o = e.querySelector("#facms-i18n-status"), n = e.querySelector("#facms-translate-loader"), r = e.querySelector("#facms-add-language");
|
|
1075
|
-
|
|
1096
|
+
R(a, t), o && (o.textContent = t), n && (n.style.display = a ? "inline-flex" : "none"), r && (r.disabled = a);
|
|
1076
1097
|
}
|
|
1077
|
-
function
|
|
1098
|
+
function R(e, t) {
|
|
1078
1099
|
const a = document.getElementById("facms-global-loader"), o = document.getElementById("facms-global-loader-label");
|
|
1079
1100
|
a && (a.style.display = e ? "flex" : "none"), o && (o.textContent = e ? t : "Loading");
|
|
1080
1101
|
}
|
|
1081
1102
|
function L(e, t) {
|
|
1082
1103
|
const a = We(t.content.nodes), o = a.length ? a.map((n) => {
|
|
1083
|
-
const r = n.items[0], s = n.items[n.items.length - 1], i = r.index === s.index ? `#${r.index + 1}` : `#${r.index + 1} - #${s.index + 1}`, c = n.items.map((l) =>
|
|
1104
|
+
const r = n.items[0], s = n.items[n.items.length - 1], i = r.index === s.index ? `#${r.index + 1}` : `#${r.index + 1} - #${s.index + 1}`, c = n.items.map((l) => Je(l.node)).filter(Boolean).join(" • "), u = n.items.length > 1 ? `${i} ${h(n.selector || "Grouped fields")} (${n.items.length} fields)` : `${i} ${h(r.node.type.toUpperCase())} • ${h(r.node.label || r.node.selector || "")}`, d = n.items.map((l) => Qe(l.node, l.index)).join("");
|
|
1084
1105
|
return `
|
|
1085
1106
|
<details class="rounded-xl p-2 border border-slate-200 dark:border-transparent bg-white dark:bg-slate-900/60 shadow-sm">
|
|
1086
1107
|
<summary class="list-none cursor-pointer flex items-center justify-between gap-2 p-3 rounded-lg bg-slate-50 dark:bg-slate-800/70 border border-slate-200 dark:border-slate-800">
|
|
@@ -1113,7 +1134,14 @@ function L(e, t) {
|
|
|
1113
1134
|
</div>
|
|
1114
1135
|
</div>
|
|
1115
1136
|
`, tt(e, t), e.querySelector("#facms-save")?.addEventListener("click", async () => {
|
|
1116
|
-
|
|
1137
|
+
let n, r;
|
|
1138
|
+
try {
|
|
1139
|
+
n = await Ze(t.content, t.locales, t.baseTextByKey), r = await Te();
|
|
1140
|
+
} catch (i) {
|
|
1141
|
+
const c = i instanceof Error ? i.message : String(i);
|
|
1142
|
+
alert(`Could not prepare publish payload: ${c}`);
|
|
1143
|
+
return;
|
|
1144
|
+
}
|
|
1117
1145
|
if (!r || r.provider === "none") {
|
|
1118
1146
|
Le(n), alert("Patch downloaded. Configure hosting in setup for one-click publish.");
|
|
1119
1147
|
return;
|
|
@@ -1122,7 +1150,7 @@ function L(e, t) {
|
|
|
1122
1150
|
qe(s, async (i) => {
|
|
1123
1151
|
let c = !1, u = "Publishing failed. Please verify token permissions and repository settings.";
|
|
1124
1152
|
try {
|
|
1125
|
-
c = await
|
|
1153
|
+
c = await Re(n, i, r);
|
|
1126
1154
|
} catch (d) {
|
|
1127
1155
|
const l = d instanceof Error ? d.message : String(d);
|
|
1128
1156
|
l && (u = `Publishing failed: ${l}`), c = !1;
|
|
@@ -1145,15 +1173,15 @@ function L(e, t) {
|
|
|
1145
1173
|
sourceKeys: Object.keys(l).length,
|
|
1146
1174
|
browserLanguage: navigator.language,
|
|
1147
1175
|
browserLanguages: navigator.languages
|
|
1148
|
-
}), t.locales[c] = p, t.languageLabels[c] = u,
|
|
1176
|
+
}), t.locales[c] = p, t.languageLabels[c] = u, q(t.languageLabels), t.activeLanguage = c, I(t.locales), _(t.content, t.locales[c], t.workingDocument, t.baseTextByKey), L(e, t), z("Manual language tab created", { lang: c }), w(e, `Added ${u} tab prefilled with source text for manual translation.`, !1), r !== "auto" || !(x?.autoTranslateEnabled ?? !0)) {
|
|
1149
1177
|
r === "auto" && !(x?.autoTranslateEnabled ?? !0) && w(e, `Privacy mode is on. Added ${u} tab for manual translation only.`, !1);
|
|
1150
1178
|
return;
|
|
1151
1179
|
}
|
|
1152
1180
|
try {
|
|
1153
1181
|
const g = Object.keys(l).length;
|
|
1154
1182
|
w(e, `Auto-filling ${u} translation... (0/${g})`, !0);
|
|
1155
|
-
const y = await _e(l, c, t.mainLanguage, (
|
|
1156
|
-
w(e, `Auto-filling ${u} translation... (${
|
|
1183
|
+
const y = await _e(l, c, t.mainLanguage, (F, b) => {
|
|
1184
|
+
w(e, `Auto-filling ${u} translation... (${F}/${b})`, !0);
|
|
1157
1185
|
});
|
|
1158
1186
|
t.locales[c] = y, I(t.locales), t.activeLanguage = c, _(t.content, y, t.workingDocument, t.baseTextByKey), L(e, t), z("Automatic translation succeeded", {
|
|
1159
1187
|
lang: c,
|
|
@@ -1171,7 +1199,7 @@ function L(e, t) {
|
|
|
1171
1199
|
});
|
|
1172
1200
|
}), at(e, t);
|
|
1173
1201
|
}
|
|
1174
|
-
function
|
|
1202
|
+
function K(e, t) {
|
|
1175
1203
|
const a = Object.keys(e), o = t && e[t] ? t : j(e), n = [...navigator.languages ?? [], navigator.language].map((r) => r.toLowerCase().split("-")[0]);
|
|
1176
1204
|
for (const r of n)
|
|
1177
1205
|
if (a.includes(r))
|
|
@@ -1185,7 +1213,7 @@ function ye(e) {
|
|
|
1185
1213
|
function nt(e) {
|
|
1186
1214
|
return new Promise((t) => window.setTimeout(t, e));
|
|
1187
1215
|
}
|
|
1188
|
-
async function
|
|
1216
|
+
async function te(e, t) {
|
|
1189
1217
|
const a = [0, 120, 280, 600, 1100, 1800, 2600];
|
|
1190
1218
|
let o = S(e, t);
|
|
1191
1219
|
if (o.nodes.length > 0)
|
|
@@ -1196,18 +1224,18 @@ async function Q(e, t) {
|
|
|
1196
1224
|
return o;
|
|
1197
1225
|
}
|
|
1198
1226
|
function ot(e, t, a) {
|
|
1199
|
-
const o =
|
|
1227
|
+
const o = re(), n = {
|
|
1200
1228
|
...a,
|
|
1201
1229
|
...o
|
|
1202
|
-
}, r =
|
|
1230
|
+
}, r = Fe(), s = Object.fromEntries(e.nodes.filter((l) => l.type === "text").map((l) => [l.key, l.value])), i = j(n), c = {
|
|
1203
1231
|
...n,
|
|
1204
1232
|
[i]: { ...n[i] ?? {}, ...s }
|
|
1205
1233
|
};
|
|
1206
1234
|
!c.en && i === "en" && (c.en = Object.assign({}, c.en ?? {}, s));
|
|
1207
|
-
const u =
|
|
1235
|
+
const u = K(c, i), d = { ...r };
|
|
1208
1236
|
return Object.keys(c).forEach((l) => {
|
|
1209
1237
|
d[l] || (d[l] = E(l));
|
|
1210
|
-
}),
|
|
1238
|
+
}), q(d), {
|
|
1211
1239
|
content: e,
|
|
1212
1240
|
locales: c,
|
|
1213
1241
|
workingDocument: t,
|
|
@@ -1227,18 +1255,18 @@ async function rt() {
|
|
|
1227
1255
|
const a = new Map(e.nodes.map((o) => [o.key, o]));
|
|
1228
1256
|
t.nodes.forEach((o) => {
|
|
1229
1257
|
const n = a.get(o.key);
|
|
1230
|
-
!n || n.type !== o.type || (o.value = n.value, n.attrs && (o.attrs = { ...n.attrs }), n.sectionItems && (o.sectionItems = [...n.sectionItems]),
|
|
1258
|
+
!n || n.type !== o.type || (o.value = n.value, n.attrs && (o.attrs = { ...n.attrs }), n.sectionItems && (o.sectionItems = [...n.sectionItems]), P(o, document));
|
|
1231
1259
|
});
|
|
1232
1260
|
}
|
|
1233
1261
|
async function st() {
|
|
1234
1262
|
await rt();
|
|
1235
1263
|
const t = {
|
|
1236
|
-
...await
|
|
1237
|
-
...
|
|
1264
|
+
...await se(),
|
|
1265
|
+
...re()
|
|
1238
1266
|
};
|
|
1239
1267
|
if (!Object.keys(t).length)
|
|
1240
1268
|
return;
|
|
1241
|
-
const a = j(t), o =
|
|
1269
|
+
const a = j(t), o = K(t, a);
|
|
1242
1270
|
if (!o || o === a)
|
|
1243
1271
|
return;
|
|
1244
1272
|
const n = S(document, location.pathname), r = t[o];
|
|
@@ -1288,56 +1316,56 @@ function it(e) {
|
|
|
1288
1316
|
});
|
|
1289
1317
|
});
|
|
1290
1318
|
};
|
|
1291
|
-
|
|
1319
|
+
pe(f), a.addEventListener("load", async () => {
|
|
1292
1320
|
const u = a.contentDocument;
|
|
1293
1321
|
if (u) {
|
|
1294
|
-
|
|
1322
|
+
R(!0, `Scanning page content for ${s}...`);
|
|
1295
1323
|
try {
|
|
1296
1324
|
let d = r.get(s);
|
|
1297
1325
|
if (d) {
|
|
1298
1326
|
d.workingDocument = u;
|
|
1299
|
-
const l = d.content.nodes.length ? S(u, s) : await
|
|
1327
|
+
const l = d.content.nodes.length ? S(u, s) : await te(u, s);
|
|
1300
1328
|
l.nodes.length && !d.content.nodes.length && (d.content = l);
|
|
1301
1329
|
} else {
|
|
1302
|
-
const l = await
|
|
1330
|
+
const l = await te(u, s);
|
|
1303
1331
|
d = ot(l, u, i), r.set(s, d);
|
|
1304
1332
|
}
|
|
1305
|
-
ye(d),
|
|
1333
|
+
ye(d), oe(d.content), L(o, d);
|
|
1306
1334
|
} finally {
|
|
1307
|
-
|
|
1335
|
+
R(!1, "Loading");
|
|
1308
1336
|
}
|
|
1309
1337
|
}
|
|
1310
|
-
}), c(), Promise.all([
|
|
1311
|
-
i = u,
|
|
1338
|
+
}), c(), Promise.all([se(), we()]).then(([u, d]) => {
|
|
1339
|
+
i = u, U = d, a.src = s;
|
|
1312
1340
|
});
|
|
1313
1341
|
}
|
|
1314
|
-
async function
|
|
1315
|
-
if (
|
|
1342
|
+
async function ae() {
|
|
1343
|
+
if (fe(), ge(), !await me())
|
|
1316
1344
|
return;
|
|
1317
|
-
const e = await
|
|
1345
|
+
const e = await be(), t = () => it(e);
|
|
1318
1346
|
if (!D) {
|
|
1319
|
-
|
|
1347
|
+
he(t);
|
|
1320
1348
|
return;
|
|
1321
1349
|
}
|
|
1322
1350
|
t();
|
|
1323
1351
|
}
|
|
1324
1352
|
async function lt() {
|
|
1325
|
-
const e = await
|
|
1353
|
+
const e = await be(), a = new URLSearchParams(location.search).get("__facms") === "1";
|
|
1326
1354
|
if (location.pathname !== e.dashboardPath && !a) {
|
|
1327
1355
|
st();
|
|
1328
1356
|
return;
|
|
1329
1357
|
}
|
|
1330
|
-
if (
|
|
1358
|
+
if (fe(), ge(), !!await me()) {
|
|
1331
1359
|
if (!D) {
|
|
1332
|
-
|
|
1333
|
-
|
|
1360
|
+
he(() => {
|
|
1361
|
+
ae();
|
|
1334
1362
|
});
|
|
1335
1363
|
return;
|
|
1336
1364
|
}
|
|
1337
|
-
|
|
1365
|
+
ae();
|
|
1338
1366
|
}
|
|
1339
1367
|
}
|
|
1340
1368
|
export {
|
|
1341
|
-
|
|
1369
|
+
ae as launchDashboard,
|
|
1342
1370
|
lt as registerCmsLauncher
|
|
1343
1371
|
};
|