@cardinali-studio/adminkit 2.1.0-rc.3 → 2.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.
- package/dist/functions/api/pages.js +35 -17
- package/package.json +1 -1
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* Sta dietro Cloudflare Access E dietro la verifica del JWT in functions/admin/_middleware.js.
|
|
17
17
|
* Secret/vars: GITHUB_TOKEN (secret), GITHUB_REPO, GITHUB_BRANCH.
|
|
18
18
|
*/
|
|
19
|
-
import { serializeItem, deserializeItem, checkFidelity, translationModel, inheritedFieldPaths, withTranslationHeader } from "../../index.js";
|
|
19
|
+
import { serializeItem, deserializeItem, checkFidelity, splitFrontMatter, translationModel, inheritedFieldPaths, withTranslationHeader } from "../../index.js";
|
|
20
20
|
import { site, pageType } from "../site.js";
|
|
21
21
|
import { getRepoSnapshot, getText, DRAFT } from "../_shared/github.js";
|
|
22
22
|
import { languageConfig, pagePath, translatedLanguages } from "../_shared/translations.js";
|
|
@@ -45,6 +45,10 @@ function json(data, status = 200) {
|
|
|
45
45
|
|
|
46
46
|
const decode64 = (b64) => decodeURIComponent(escape(atob(String(b64 || "").replace(/\n/g, ""))));
|
|
47
47
|
|
|
48
|
+
const own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
49
|
+
const normalizedBody = (value) => String(value ?? "").replace(/^\n+/, "").replace(/\s+$/, "");
|
|
50
|
+
const sameValue = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
51
|
+
|
|
48
52
|
async function readFile(env, repo, branch, path) {
|
|
49
53
|
const res = await gh(env, `/repos/${repo}/contents/${path}?ref=${branch}`);
|
|
50
54
|
if (!res.ok) return null;
|
|
@@ -276,28 +280,42 @@ async function commitPages(args, attempt = 0) {
|
|
|
276
280
|
const definition = pageType(p.type || typeOf(oldMd));
|
|
277
281
|
if (!definition) { invalidTypes.push(p.slug); continue; }
|
|
278
282
|
|
|
283
|
+
/* Un salvataggio porta con sé anche riferimenti alle pagine che l'utente non ha
|
|
284
|
+
modificato. Non riscriverle (né sottoporle alla guardia di fedeltà): una pagina
|
|
285
|
+
legacy che il pannello non sa ancora riprodurre non deve impedire di salvare una
|
|
286
|
+
traduzione di tutt'altra pagina. I soli campi espliciti del payload possono invece
|
|
287
|
+
richiedere una riscrittura, per esempio dopo un riordino. */
|
|
288
|
+
const sourceModel = oldMd ? deserializeItem(oldMd, definition.shape, { slug: sourceSlug }) : {};
|
|
289
|
+
const sourceBody = oldMd ? normalizedBody(splitFrontMatter(oldMd).body) : "";
|
|
290
|
+
const defaultChanged = !oldMd ||
|
|
291
|
+
Object.keys(definition.shape).some((key) => own(p, key) && !sameValue(p[key], sourceModel[key])) ||
|
|
292
|
+
(own(p, "body") && normalizedBody(p.body) !== sourceBody);
|
|
293
|
+
const defaultModel = { ...sourceModel, ...p };
|
|
294
|
+
|
|
279
295
|
// GUARDIA DI FEDELTÀ: se non sappiamo riprodurre il file che stiamo per sovrascrivere,
|
|
280
296
|
// non lo sovrascriviamo. Intercetta i costrutti che il lettore del front matter non regge
|
|
281
297
|
// e trasforma una corruzione silenziosa in un rifiuto visibile.
|
|
282
|
-
if (oldMd) {
|
|
298
|
+
if (oldMd && defaultChanged) {
|
|
283
299
|
const f = checkFidelity(oldMd, definition.shape, { slug: sourceSlug });
|
|
284
300
|
if (!f.ok) { rejected.push(sourceSlug); continue; }
|
|
285
301
|
}
|
|
286
302
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
303
|
+
if (defaultChanged) {
|
|
304
|
+
entries.push({
|
|
305
|
+
path: `content/${p.slug}/index.md`,
|
|
306
|
+
mode: "100644",
|
|
307
|
+
type: "blob",
|
|
308
|
+
content: serializeItem(p, {
|
|
309
|
+
shape: definition.shape,
|
|
310
|
+
oldMd,
|
|
311
|
+
// Solo per i tipi che un corpo ce l'hanno: su una gallery il segnaposto sarebbe
|
|
312
|
+
// testo scritto nel repo che non compare da nessuna parte (vedi hasBody).
|
|
313
|
+
placeholderBody: definition.hasBody
|
|
314
|
+
? (m) => `Placeholder content for **${m.title || p.slug}**.`
|
|
315
|
+
: undefined,
|
|
316
|
+
}),
|
|
317
|
+
});
|
|
318
|
+
}
|
|
301
319
|
|
|
302
320
|
/* Una lingua secondaria arriva esplicitamente dal client solo se è stata aperta o
|
|
303
321
|
* modificata. Non creare file vuoti per ogni pagina: la prima apertura di EN li mostra
|
|
@@ -314,7 +332,7 @@ async function commitPages(args, attempt = 0) {
|
|
|
314
332
|
if (!fidelity.ok) { rejected.push(`${p.slug}.${code}`); continue; }
|
|
315
333
|
}
|
|
316
334
|
const candidate = update.page && typeof update.page === "object" ? update.page : update;
|
|
317
|
-
const translated = translationModel(definition.shape,
|
|
335
|
+
const translated = translationModel(definition.shape, defaultModel, candidate);
|
|
318
336
|
if (definition.hasBody) {
|
|
319
337
|
if (typeof update.body === "string") translated.body = update.body;
|
|
320
338
|
else if (!oldTranslation && typeof p.body === "string") translated.body = p.body;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cardinali-studio/adminkit",
|
|
3
|
-
"version": "2.1.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Motore riusabile di un pannello di amministrazione per siti Hugo su Cloudflare Pages: codec del front matter guidato dallo schema, form React, libreria media su R2. NIENTE di specifico di un sito qui dentro.",
|
|
6
6
|
"license": "UNLICENSED",
|