@materializecms/server 0.8.0 → 0.9.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/CHANGELOG.md +34 -0
- package/package.json +4 -4
- package/src/admin.js +3 -2
- package/src/ai.js +17 -16
- package/src/app.d.ts +5 -0
- package/src/app.js +518 -264
- package/src/brief.js +3 -2
- package/src/en/api.d.ts +2 -0
- package/src/en/api.js +199 -0
- package/src/en/index.d.ts +5 -0
- package/src/en/index.js +7 -0
- package/src/en/services.d.ts +2 -0
- package/src/en/services.js +154 -0
- package/src/forms.d.ts +6 -3
- package/src/forms.js +22 -11
- package/src/index.d.ts +13 -0
- package/src/index.js +52 -2
- package/src/lang.d.ts +7 -0
- package/src/lang.js +17 -0
- package/src/mail.d.ts +6 -2
- package/src/mail.js +73 -40
- package/src/media.js +3 -2
- package/src/offsite.js +12 -9
- package/src/remote-storage.js +24 -23
- package/src/remote.d.ts +25 -8
- package/src/remote.js +210 -45
- package/src/status-page.js +9 -4
- package/src/t.d.ts +2 -0
- package/src/t.js +4 -0
- package/src/tools.js +28 -27
- package/src/wordpress.js +12 -11
- package/src/wpimport.js +27 -23
package/src/wpimport.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { slugify } from '@materializecms/core';
|
|
2
|
+
import { t } from './t.js';
|
|
2
3
|
import { htmlToPage, htmlToRichText, imageAltsIn, mainContent, originalOf, plain, } from './wordpress.js';
|
|
3
4
|
/** Which sources fit a field of this kind. */
|
|
4
5
|
export function sourcesFor(f) {
|
|
@@ -117,10 +118,10 @@ export async function runImport(site, plan, deps) {
|
|
|
117
118
|
};
|
|
118
119
|
const report = () => deps.onProgress({ ...progress });
|
|
119
120
|
const targetOf = (item) => (item.kind === 'post' ? plan.posts : plan.pages);
|
|
120
|
-
const defOf = (
|
|
121
|
+
const defOf = (target) => deps.collections.find((c) => c.name === target.collection);
|
|
121
122
|
const items = site.items.filter((i) => {
|
|
122
|
-
const
|
|
123
|
-
return
|
|
123
|
+
const target = targetOf(i);
|
|
124
|
+
return target && defOf(target);
|
|
124
125
|
});
|
|
125
126
|
// 0. Items the API gave empty (some themes and page builders keep the page elsewhere): their
|
|
126
127
|
// published page is read instead, between its header and its footer.
|
|
@@ -134,8 +135,8 @@ export async function runImport(site, plan, deps) {
|
|
|
134
135
|
// 1. Images: each address once, the original size when WordPress has it.
|
|
135
136
|
const wanted = new Map();
|
|
136
137
|
for (const item of items) {
|
|
137
|
-
const
|
|
138
|
-
const fields = Object.values(
|
|
138
|
+
const target = targetOf(item);
|
|
139
|
+
const fields = Object.values(target.fields);
|
|
139
140
|
if (fields.includes('content'))
|
|
140
141
|
for (const [src, alt] of imageAltsIn(item.html)) {
|
|
141
142
|
const url = new URL(src, site.url).href;
|
|
@@ -171,14 +172,14 @@ export async function runImport(site, plan, deps) {
|
|
|
171
172
|
await Promise.all([worker(), worker(), worker()]);
|
|
172
173
|
// 2. Where every item will live, so links between them point to the new pages.
|
|
173
174
|
const plans = items.map((item) => {
|
|
174
|
-
const
|
|
175
|
-
const def = defOf(
|
|
175
|
+
const target = targetOf(item);
|
|
176
|
+
const def = defOf(target);
|
|
176
177
|
const slug = slugify(decodeURIComponent(item.slug)) || slugify(item.title) || item.sourceId;
|
|
177
178
|
const sample = {};
|
|
178
|
-
for (const [name, source] of Object.entries(
|
|
179
|
+
for (const [name, source] of Object.entries(target.fields))
|
|
179
180
|
if (source === 'slug')
|
|
180
181
|
sample[name] = slug;
|
|
181
|
-
return { item,
|
|
182
|
+
return { item, target, def, slug, url: deps.urlOf(def, sample) };
|
|
182
183
|
});
|
|
183
184
|
const moved = new Map();
|
|
184
185
|
for (const p of plans) {
|
|
@@ -224,7 +225,7 @@ export async function runImport(site, plan, deps) {
|
|
|
224
225
|
// Canvas pages filled from the content: the ones the AI may lay out again.
|
|
225
226
|
const canvas = [];
|
|
226
227
|
for (const entry of plans) {
|
|
227
|
-
const { item,
|
|
228
|
+
const { item, target, def } = entry;
|
|
228
229
|
let { slug, url } = entry;
|
|
229
230
|
try {
|
|
230
231
|
const mine = taken.get(def.name) ?? new Set();
|
|
@@ -236,23 +237,26 @@ export async function runImport(site, plan, deps) {
|
|
|
236
237
|
const before = slug;
|
|
237
238
|
slug = `${slug}-${n}`;
|
|
238
239
|
const sample = {};
|
|
239
|
-
for (const [name, source] of Object.entries(
|
|
240
|
+
for (const [name, source] of Object.entries(target.fields))
|
|
240
241
|
if (source === 'slug')
|
|
241
242
|
sample[name] = slug;
|
|
242
243
|
url = deps.urlOf(def, sample);
|
|
243
244
|
progress.problems.push({
|
|
244
245
|
title: item.title,
|
|
245
|
-
reason:
|
|
246
|
+
reason: t('indirizzo già usato da un’altra pagina importata: ora è {now}, era {before}', {
|
|
247
|
+
now: url ?? slug,
|
|
248
|
+
before,
|
|
249
|
+
}),
|
|
246
250
|
});
|
|
247
251
|
}
|
|
248
252
|
else if (await deps.exists(def.name, slug)) {
|
|
249
253
|
// Already there from before (a second import): left as it is.
|
|
250
|
-
progress.skipped.push({ title: item.title, reason: 'c’è già un contenuto con lo stesso indirizzo' });
|
|
254
|
+
progress.skipped.push({ title: item.title, reason: t('c’è già un contenuto con lo stesso indirizzo') });
|
|
251
255
|
continue;
|
|
252
256
|
}
|
|
253
257
|
mine.add(slug);
|
|
254
258
|
const data = {};
|
|
255
|
-
for (const [name, source] of Object.entries(
|
|
259
|
+
for (const [name, source] of Object.entries(target.fields)) {
|
|
256
260
|
const f = def.fields[name];
|
|
257
261
|
if (!f)
|
|
258
262
|
continue;
|
|
@@ -260,7 +264,7 @@ export async function runImport(site, plan, deps) {
|
|
|
260
264
|
if (value !== undefined)
|
|
261
265
|
data[name] = value;
|
|
262
266
|
}
|
|
263
|
-
for (const [name, source] of Object.entries(
|
|
267
|
+
for (const [name, source] of Object.entries(target.fields))
|
|
264
268
|
if (source === 'slug')
|
|
265
269
|
data[name] = slug;
|
|
266
270
|
const doc = await deps.create(def, data);
|
|
@@ -271,10 +275,10 @@ export async function runImport(site, plan, deps) {
|
|
|
271
275
|
published = true;
|
|
272
276
|
}
|
|
273
277
|
catch {
|
|
274
|
-
progress.problems.push({ title: doc.title, reason: 'importato come bozza: ha campi da completare' });
|
|
278
|
+
progress.problems.push({ title: doc.title, reason: t('importato come bozza: ha campi da completare') });
|
|
275
279
|
}
|
|
276
280
|
progress.created.push({ id: doc.id, collection: def.name, title: doc.title, published });
|
|
277
|
-
if (Object.entries(
|
|
281
|
+
if (Object.entries(target.fields).some(([name, source]) => source === 'content' && def.fields[name]?.kind === 'page'))
|
|
278
282
|
canvas.push({ id: doc.id, collection: def.name, title: doc.title });
|
|
279
283
|
const from = pathOf(item.link, site.url);
|
|
280
284
|
if (published && from && url && from !== url)
|
|
@@ -301,14 +305,14 @@ export async function runImport(site, plan, deps) {
|
|
|
301
305
|
try {
|
|
302
306
|
const why = await deps.relayout(doc);
|
|
303
307
|
if (why)
|
|
304
|
-
progress.problems.push({ title: doc.title, reason:
|
|
308
|
+
progress.problems.push({ title: doc.title, reason: t('impaginazione semplice lasciata: {why}', { why }) });
|
|
305
309
|
else
|
|
306
310
|
progress.relaid++;
|
|
307
311
|
}
|
|
308
312
|
catch (error) {
|
|
309
313
|
progress.problems.push({
|
|
310
314
|
title: doc.title,
|
|
311
|
-
reason:
|
|
315
|
+
reason: t('l’AI non ha rifatto l’impaginazione: {detail}', { detail: error.message }),
|
|
312
316
|
});
|
|
313
317
|
}
|
|
314
318
|
progress.done++;
|
|
@@ -423,16 +427,16 @@ export function relayoutProblem(before, after) {
|
|
|
423
427
|
const was = wordsOf(before);
|
|
424
428
|
const now = wordsOf(after);
|
|
425
429
|
if (!now.size)
|
|
426
|
-
return 'la pagina sarebbe rimasta vuota';
|
|
430
|
+
return t('la pagina sarebbe rimasta vuota');
|
|
427
431
|
const lost = [...was].filter((w) => !now.has(w)).length;
|
|
428
432
|
const added = [...now].filter((w) => !was.has(w)).length;
|
|
429
433
|
if (lost > Math.max(3, was.size * 0.1))
|
|
430
|
-
return 'l’AI avrebbe tolto parte del testo';
|
|
434
|
+
return t('l’AI avrebbe tolto parte del testo');
|
|
431
435
|
if (added > Math.max(8, was.size * 0.15))
|
|
432
|
-
return 'l’AI avrebbe aggiunto testi che non c’erano';
|
|
436
|
+
return t('l’AI avrebbe aggiunto testi che non c’erano');
|
|
433
437
|
const pictures = imagesOf(after);
|
|
434
438
|
if ([...imagesOf(before)].some((src) => !pictures.has(src)))
|
|
435
|
-
return 'l’AI avrebbe tolto delle immagini';
|
|
439
|
+
return t('l’AI avrebbe tolto delle immagini');
|
|
436
440
|
return null;
|
|
437
441
|
}
|
|
438
442
|
/** Descriptions the page had for its images, put back where the new layout left them empty. */
|