@aduptive/strapi-blockscene 1.0.0-alpha.7 → 1.0.0-alpha.9
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/README.md +243 -27
- package/dist/admin.cjs +2696 -670
- package/dist/admin.mjs +2717 -689
- package/dist/server.cjs +253 -20
- package/package.json +1 -1
package/dist/server.cjs
CHANGED
|
@@ -106,7 +106,41 @@ var require_groups = __commonJS({
|
|
|
106
106
|
const [, end] = groupRange(rows, start, g);
|
|
107
107
|
return [...rows.slice(0, start), ...rows.slice(end + 1)];
|
|
108
108
|
}
|
|
109
|
-
|
|
109
|
+
var MAX_COLUMNS = 12;
|
|
110
|
+
var parseColumns = (value) => {
|
|
111
|
+
const n = typeof value === "number" ? value : typeof value === "string" && /^\s*\d{1,3}\s*$/.test(value) ? Number(value) : NaN;
|
|
112
|
+
return Number.isInteger(n) && n >= 1 ? n : null;
|
|
113
|
+
};
|
|
114
|
+
var columnsAttribute = (attr) => Boolean(attr) && typeof attr === "object" && !attr.private && (["integer", "biginteger", "float", "decimal", "string"].includes(attr.type) || attr.type === "enumeration" && Array.isArray(attr.enum) && attr.enum.length > 0 && attr.enum.every((value) => parseColumns(value) !== null));
|
|
115
|
+
var layoutFields2 = (schema) => Object.entries(schema?.attributes || {}).filter(([, attr]) => columnsAttribute(attr)).map(([name]) => name);
|
|
116
|
+
function validLayout(value, attributes) {
|
|
117
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
118
|
+
if (!Object.keys(value).every((key) => ["columnsField", "mobileColumnsField", "maxColumns"].includes(key))) return false;
|
|
119
|
+
const field = (name) => typeof name === "string" && /^[A-Za-z_][\w-]{0,63}$/.test(name) && (!attributes || columnsAttribute(attributes[name]));
|
|
120
|
+
return field(value.columnsField) && (value.mobileColumnsField === void 0 || field(value.mobileColumnsField)) && (value.maxColumns === void 0 || Number.isInteger(value.maxColumns) && value.maxColumns >= 1 && value.maxColumns <= MAX_COLUMNS);
|
|
121
|
+
}
|
|
122
|
+
function layoutColumns(row, layout, schema) {
|
|
123
|
+
const max = layout.maxColumns || MAX_COLUMNS;
|
|
124
|
+
const read = (name) => Math.min(max, parseColumns(row?.[name]) ?? parseColumns(schema?.attributes?.[name]?.default) ?? 1);
|
|
125
|
+
return { desktop: read(layout.columnsField), mobile: layout.mobileColumnsField ? read(layout.mobileColumnsField) : null };
|
|
126
|
+
}
|
|
127
|
+
module2.exports = {
|
|
128
|
+
safeGroups: safeGroups2,
|
|
129
|
+
validateGroups: validateGroups2,
|
|
130
|
+
groupRange,
|
|
131
|
+
groupRows,
|
|
132
|
+
topLevelRanges,
|
|
133
|
+
moveGroup,
|
|
134
|
+
removeGroup,
|
|
135
|
+
blockKey,
|
|
136
|
+
isOpener,
|
|
137
|
+
isClose,
|
|
138
|
+
MAX_COLUMNS,
|
|
139
|
+
parseColumns,
|
|
140
|
+
layoutFields: layoutFields2,
|
|
141
|
+
validLayout,
|
|
142
|
+
layoutColumns
|
|
143
|
+
};
|
|
110
144
|
}
|
|
111
145
|
});
|
|
112
146
|
|
|
@@ -237,7 +271,7 @@ var require_settings = __commonJS({
|
|
|
237
271
|
return [...facets];
|
|
238
272
|
}
|
|
239
273
|
var safeUrl2 = (value) => typeof value === "string" && (/^\/(?!\/)/.test(value) || /^https?:\/\//.test(value)) ? value : void 0;
|
|
240
|
-
var { safeGroups: safeGroups2 } = require_groups();
|
|
274
|
+
var { safeGroups: safeGroups2, validLayout } = require_groups();
|
|
241
275
|
var safeVersion = (value) => typeof value === "string" && /^[\w.-]{1,32}$/.test(value) ? value : void 0;
|
|
242
276
|
var fail2 = (message, details) => {
|
|
243
277
|
let ValidationError;
|
|
@@ -268,6 +302,7 @@ var require_settings = __commonJS({
|
|
|
268
302
|
}
|
|
269
303
|
for (const [uid, schema] of Object.entries(config.schemas || {})) {
|
|
270
304
|
const entry = entries[uid] ||= {};
|
|
305
|
+
for (const [key, value] of Object.entries(config.blocks?.[uid] || {})) if (entry[key] === void 0) entry[key] = value;
|
|
271
306
|
entry.facets = facetsOf(uid, schema, config.schemas);
|
|
272
307
|
entry.typology ||= guessTypology(uid, schema?.info?.displayName);
|
|
273
308
|
entry.tags ||= [];
|
|
@@ -282,7 +317,7 @@ var require_settings = __commonJS({
|
|
|
282
317
|
groups: safeGroups2(config.groups, config.componentUids)
|
|
283
318
|
};
|
|
284
319
|
}
|
|
285
|
-
function validateSettings2(input, componentUids2, contentTypeUids2 = [], historyTypes = null) {
|
|
320
|
+
function validateSettings2(input, componentUids2, contentTypeUids2 = [], historyTypes = null, schemas = null) {
|
|
286
321
|
const types = typeMap(contentTypeUids2);
|
|
287
322
|
if (!input || typeof input !== "object" || Array.isArray(input)) fail2("Settings must be an object");
|
|
288
323
|
if (JSON.stringify(input).length > 64 * 1024) fail2("Settings payload too large");
|
|
@@ -318,6 +353,9 @@ var require_settings = __commonJS({
|
|
|
318
353
|
} else if (key === "mediaId") {
|
|
319
354
|
if (!Number.isInteger(entry.mediaId) || entry.mediaId <= 0) fail2(`Invalid media for "${uid}"`);
|
|
320
355
|
clean.mediaId = entry.mediaId;
|
|
356
|
+
} else if (key === "layout") {
|
|
357
|
+
if (!validLayout(entry.layout, schemas && (schemas[uid]?.attributes || {}))) fail2(`Invalid layout for "${uid}": columnsField (and mobileColumnsField) must name a number, string or numeric enumeration attribute of the component; maxColumns 1 to 12`);
|
|
358
|
+
clean.layout = structuredClone(entry.layout);
|
|
321
359
|
} else fail2(`Unknown component setting "${key}"`);
|
|
322
360
|
}
|
|
323
361
|
if (Object.keys(clean).length) out.components[uid] = clean;
|
|
@@ -343,7 +381,7 @@ var require_settings = __commonJS({
|
|
|
343
381
|
if (out.history.eventDays < out.history.retentionDays) fail2("history.eventDays must be at least history.retentionDays");
|
|
344
382
|
return out;
|
|
345
383
|
}
|
|
346
|
-
function mergeSaved2(saved, componentUids2, contentTypeUids2 = [], historyTypes = null) {
|
|
384
|
+
function mergeSaved2(saved, componentUids2, contentTypeUids2 = [], historyTypes = null, schemas = null) {
|
|
347
385
|
const types = typeMap(contentTypeUids2);
|
|
348
386
|
const out = structuredClone(DEFAULTS2);
|
|
349
387
|
if (!saved || typeof saved !== "object") return out;
|
|
@@ -373,6 +411,7 @@ var require_settings = __commonJS({
|
|
|
373
411
|
clean.tags = cleanTags(clean.tags);
|
|
374
412
|
if (!clean.tags.length) delete clean.tags;
|
|
375
413
|
}
|
|
414
|
+
if ("layout" in clean && !validLayout(clean.layout, schemas && (schemas[uid]?.attributes || {}))) delete clean.layout;
|
|
376
415
|
if (Object.keys(clean).length) out.components[uid] = clean;
|
|
377
416
|
}
|
|
378
417
|
for (const [uid, entry] of Object.entries(saved.contentTypes || {})) {
|
|
@@ -411,7 +450,7 @@ var require_settings = __commonJS({
|
|
|
411
450
|
var FIELD_TEXT = { label: 80, description: 300, placeholder: 120, help: 500 };
|
|
412
451
|
var LOCALE = /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
|
|
413
452
|
var plain = (value) => value && typeof value === "object" && !Array.isArray(value);
|
|
414
|
-
var fieldText = (value, max) => typeof value === "string" ? value.trim() !== "" && value.length <= max : plain(value) && Object.keys(value).length > 0 && Object.keys(value).length <= 30 && Object.entries(value).every(([locale,
|
|
453
|
+
var fieldText = (value, max) => typeof value === "string" ? value.trim() !== "" && value.length <= max : plain(value) && Object.keys(value).length > 0 && Object.keys(value).length <= 30 && Object.entries(value).every(([locale, text2]) => LOCALE.test(locale) && fieldText(text2, max));
|
|
415
454
|
function validateFields2(input, schemas = {}, stale = []) {
|
|
416
455
|
if (input === null || input === void 0) return {};
|
|
417
456
|
if (!plain(input)) fail2("fields must be an object");
|
|
@@ -435,6 +474,151 @@ var require_settings = __commonJS({
|
|
|
435
474
|
}
|
|
436
475
|
return out;
|
|
437
476
|
}
|
|
477
|
+
var str = (max) => (value) => typeof value === "string" && value.trim() !== "" && value.length <= max;
|
|
478
|
+
var BLOCK_META = { label: str(80), typology: (value) => TYPOLOGIES2.includes(value), tags: validTags, keywords: str(500), image: (value) => safeUrl2(value) !== void 0 };
|
|
479
|
+
var localize = (holder, key, source, locale, text2) => {
|
|
480
|
+
holder[key] = { ...plain(holder[key]) ? holder[key] : { en: holder[key] ?? source }, [locale]: text2 };
|
|
481
|
+
};
|
|
482
|
+
function schemaMetadata2(schemas = {}, translations = null, notes = []) {
|
|
483
|
+
const blocks = {}, fields = {};
|
|
484
|
+
const own = (holder, where) => {
|
|
485
|
+
const value = holder?.pluginOptions?.blockscene;
|
|
486
|
+
if (value === void 0 || plain(value)) return value || {};
|
|
487
|
+
notes.push(`${where}: pluginOptions.blockscene must be an object`);
|
|
488
|
+
return {};
|
|
489
|
+
};
|
|
490
|
+
for (const [uid, schema] of Object.entries(schemas)) {
|
|
491
|
+
if (!uid.includes("::")) {
|
|
492
|
+
const block = {};
|
|
493
|
+
for (const [key, value] of Object.entries(own(schema, uid))) {
|
|
494
|
+
if (!Object.hasOwn(BLOCK_META, key)) notes.push(`${uid}: unknown key "${key}"`);
|
|
495
|
+
else if (!BLOCK_META[key](value)) notes.push(`${uid}: invalid ${key}`);
|
|
496
|
+
else block[key] = key === "tags" ? cleanTags(value) : value;
|
|
497
|
+
}
|
|
498
|
+
if (typeof schema?.info?.description === "string" && schema.info.description.trim()) block.description = schema.info.description;
|
|
499
|
+
if (Object.keys(block).length) blocks[uid] = block;
|
|
500
|
+
}
|
|
501
|
+
for (const [name, attr] of Object.entries(schema?.attributes || {})) {
|
|
502
|
+
const texts = {};
|
|
503
|
+
for (const [key, value] of Object.entries(own(attr, `${uid}.${name}`))) {
|
|
504
|
+
if (!Object.hasOwn(FIELD_TEXT, key)) notes.push(`${uid}.${name}: unknown key "${key}"`);
|
|
505
|
+
else if (!str(FIELD_TEXT[key])(value)) notes.push(`${uid}.${name}: ${key} must be a string of 1 to ${FIELD_TEXT[key]} characters`);
|
|
506
|
+
else texts[key] = value;
|
|
507
|
+
}
|
|
508
|
+
if (Object.keys(texts).length) (fields[uid] ||= {})[name] = texts;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
if (translations != null && !plain(translations)) {
|
|
512
|
+
notes.push('translations must be { "<locale>": { "<key>": text } }');
|
|
513
|
+
translations = null;
|
|
514
|
+
}
|
|
515
|
+
const stale = [];
|
|
516
|
+
for (const [locale, entries] of Object.entries(translations || {})) {
|
|
517
|
+
if (!LOCALE.test(locale) || !plain(entries) || JSON.stringify(entries).length > 256 * 1024) {
|
|
518
|
+
notes.push(`translations "${locale}" ignored: expected a locale code with a flat { "<key>": text } map under 256 KB`);
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
for (const [key, text2] of Object.entries(entries)) {
|
|
522
|
+
const uid = Object.keys(schemas).find((uid2) => key === uid2 || key.startsWith(`${uid2}.`));
|
|
523
|
+
const [name, part = "label", extra] = uid ? key.slice(uid.length + 1).split(".") : [];
|
|
524
|
+
const block = uid && !uid.includes("::");
|
|
525
|
+
const target = block && key === uid ? [blocks[uid] ||= {}, "label", schemas[uid]?.info?.displayName || uid, 80] : block && key === `${uid}.description` ? [blocks[uid] ||= {}, "description", null, 300] : uid && Object.hasOwn(schemas[uid]?.attributes || {}, name) && Object.hasOwn(FIELD_TEXT, part) && extra === void 0 ? [null, part, null, FIELD_TEXT[part]] : null;
|
|
526
|
+
if (!target) {
|
|
527
|
+
stale.push(`${locale} "${key}"`);
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
const [holder, field, source, max] = target;
|
|
531
|
+
if (!str(max)(text2)) {
|
|
532
|
+
notes.push(`translations ${locale} "${key}": a string of 1 to ${max} characters`);
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
localize(holder || ((fields[uid] ||= {})[name] ||= {}), field, source, locale, text2);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (stale.length) notes.push(`translation keys naming no block or field were skipped: ${stale.slice(0, 20).join(", ")}${stale.length > 20 ? ` and ${stale.length - 20} more` : ""}`);
|
|
539
|
+
return { blocks, fields };
|
|
540
|
+
}
|
|
541
|
+
var VARIANT = { id: /^[a-z0-9][a-z0-9_-]{0,39}$/, perComponent: 12, bytes: 16 * 1024, total: 256 * 1024, items: 100 };
|
|
542
|
+
var text = (value) => typeof value === "string";
|
|
543
|
+
var finite = (value) => typeof value === "number" && Number.isFinite(value);
|
|
544
|
+
var SCALARS = {
|
|
545
|
+
string: text,
|
|
546
|
+
text,
|
|
547
|
+
richtext: text,
|
|
548
|
+
email: text,
|
|
549
|
+
uid: text,
|
|
550
|
+
date: text,
|
|
551
|
+
datetime: text,
|
|
552
|
+
time: text,
|
|
553
|
+
timestamp: text,
|
|
554
|
+
integer: Number.isInteger,
|
|
555
|
+
biginteger: (value) => Number.isInteger(value) || text(value) && /^-?\d{1,19}$/.test(value),
|
|
556
|
+
float: finite,
|
|
557
|
+
decimal: finite,
|
|
558
|
+
boolean: (value) => typeof value === "boolean",
|
|
559
|
+
json: () => true,
|
|
560
|
+
customField: () => true,
|
|
561
|
+
blocks: Array.isArray,
|
|
562
|
+
enumeration: (value, attr) => (attr.enum || []).includes(value)
|
|
563
|
+
};
|
|
564
|
+
function variantValues(values, schema, schemas, path, skipped) {
|
|
565
|
+
if (!plain(values)) throw new Error(`${path} must be an object`);
|
|
566
|
+
const out = {};
|
|
567
|
+
for (const [name, value] of Object.entries(values)) {
|
|
568
|
+
if (name === "id" || name === "__component") continue;
|
|
569
|
+
const attr = schema.attributes?.[name], at = `${path}.${name}`;
|
|
570
|
+
if (!attr) throw new Error(`${at} is not an attribute of the component`);
|
|
571
|
+
if (attr.type === "media" || attr.type === "relation") {
|
|
572
|
+
skipped.push(at);
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
if (attr.type === "component") {
|
|
576
|
+
const nested = schemas[attr.component], max = Math.min(attr.max ?? Infinity, VARIANT.items);
|
|
577
|
+
if (!nested) throw new Error(`${at}: unknown component "${attr.component}"`);
|
|
578
|
+
if (!attr.repeatable) out[name] = value === null ? null : variantValues(value, nested, schemas, at, skipped);
|
|
579
|
+
else if (!Array.isArray(value) || value.length > max) throw new Error(`${at} must be a list of at most ${max} items`);
|
|
580
|
+
else out[name] = value.map((item, index) => variantValues(item, nested, schemas, `${at}[${index}]`, skipped));
|
|
581
|
+
} else if (value === null || SCALARS[attr.type]?.(value, attr)) out[name] = structuredClone(value);
|
|
582
|
+
else throw new Error(`${at}: ${SCALARS[attr.type] ? `not a valid ${attr.type}` : `${attr.type} values are not supported`}`);
|
|
583
|
+
}
|
|
584
|
+
return out;
|
|
585
|
+
}
|
|
586
|
+
function validateVariants2(config, schemas = {}, notes = []) {
|
|
587
|
+
const out = {};
|
|
588
|
+
let total = 0;
|
|
589
|
+
for (const [uid, entry] of Object.entries(plain(config) ? config : {})) {
|
|
590
|
+
if (!plain(entry) || entry.variants === void 0) continue;
|
|
591
|
+
if (!schemas[uid]) {
|
|
592
|
+
notes.push(`${uid}: unknown component`);
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
595
|
+
if (!Array.isArray(entry.variants) || entry.variants.length > VARIANT.perComponent) {
|
|
596
|
+
notes.push(`${uid}: variants must be a list of at most ${VARIANT.perComponent}`);
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
const ids = /* @__PURE__ */ new Set();
|
|
600
|
+
entry.variants.forEach((variant, index) => {
|
|
601
|
+
const name = `${uid} variant "${variant?.id ?? index}"`;
|
|
602
|
+
try {
|
|
603
|
+
if (!plain(variant) || Object.keys(variant).some((key) => !["id", "label", "values"].includes(key))) throw new Error("expected { id, label, values }");
|
|
604
|
+
if (!text(variant.id) || !VARIANT.id.test(variant.id) || ids.has(variant.id)) throw new Error('id must be 1 to 40 lowercase letters, digits, "-" or "_", unique per component');
|
|
605
|
+
if (!fieldText(variant.label, 60)) throw new Error('label must be a string of 1 to 60 characters, or { "<locale>": string }');
|
|
606
|
+
const skipped = [];
|
|
607
|
+
const values = variantValues(variant.values ?? {}, schemas[uid], schemas, "values", skipped);
|
|
608
|
+
const size = JSON.stringify(values).length;
|
|
609
|
+
if (size > VARIANT.bytes) throw new Error(`values over ${VARIANT.bytes / 1024} KB`);
|
|
610
|
+
if (total + size > VARIANT.total) throw new Error(`all variants together over ${VARIANT.total / 1024} KB`);
|
|
611
|
+
if (skipped.length) notes.push(`${name}: media and relation values are not inserted (${skipped.slice(0, 5).join(", ")}${skipped.length > 5 ? ", ..." : ""})`);
|
|
612
|
+
ids.add(variant.id);
|
|
613
|
+
total += size;
|
|
614
|
+
(out[uid] ||= []).push({ id: variant.id, label: structuredClone(variant.label), values });
|
|
615
|
+
} catch (error) {
|
|
616
|
+
notes.push(`${name} ignored: ${error.message}`);
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
return out;
|
|
621
|
+
}
|
|
438
622
|
var PREFS = { starred: 200, recent: 20 };
|
|
439
623
|
function validatePrefs2(input, componentUids2) {
|
|
440
624
|
if (!input || typeof input !== "object" || Array.isArray(input)) fail2("Preferences must be an object");
|
|
@@ -447,7 +631,7 @@ var require_settings = __commonJS({
|
|
|
447
631
|
return out;
|
|
448
632
|
}
|
|
449
633
|
var mergePrefs2 = (saved, componentUids2) => Object.fromEntries(Object.entries(PREFS).map(([key, max]) => [key, Array.isArray(saved?.[key]) ? [...new Set(saved[key].filter((uid) => componentUids2.includes(uid)))].slice(0, max) : []]));
|
|
450
|
-
module2.exports = { PLUGIN: PLUGIN2, HIDDEN_MODES, TEMPLATES: TEMPLATES2, TYPOLOGIES: TYPOLOGIES2, guessTypology, facetsOf, validatePrefs: validatePrefs2, mergePrefs: mergePrefs2, ICONS, DEFAULTS: DEFAULTS2, catalog: catalog2, validateSettings: validateSettings2, validateFields: validateFields2, mergeSaved: mergeSaved2, layer: layer2, overrides: overrides2, safeUrl: safeUrl2, fail: fail2 };
|
|
634
|
+
module2.exports = { PLUGIN: PLUGIN2, HIDDEN_MODES, TEMPLATES: TEMPLATES2, TYPOLOGIES: TYPOLOGIES2, guessTypology, facetsOf, validatePrefs: validatePrefs2, mergePrefs: mergePrefs2, ICONS, DEFAULTS: DEFAULTS2, catalog: catalog2, validateSettings: validateSettings2, validateFields: validateFields2, validateVariants: validateVariants2, schemaMetadata: schemaMetadata2, mergeSaved: mergeSaved2, layer: layer2, overrides: overrides2, safeUrl: safeUrl2, fail: fail2 };
|
|
451
635
|
}
|
|
452
636
|
});
|
|
453
637
|
|
|
@@ -475,6 +659,22 @@ var require_hidden = __commonJS({
|
|
|
475
659
|
}
|
|
476
660
|
return { added, skipped };
|
|
477
661
|
}
|
|
662
|
+
function hideFromBuilder2(services, uids, name) {
|
|
663
|
+
const has = new Set(uids);
|
|
664
|
+
const drop = (attributes) => Array.isArray(attributes) ? attributes.filter((attr) => attr?.name !== name) : attributes && typeof attributes === "object" ? Object.fromEntries(Object.entries(attributes).filter(([key]) => key !== name)) : attributes;
|
|
665
|
+
const extend = (uid, wrap) => {
|
|
666
|
+
if (services?.get?.(uid)) services.extend(uid, wrap);
|
|
667
|
+
};
|
|
668
|
+
extend("plugin::content-type-builder.components", (service) => ({ ...service, formatComponent(component, ...rest) {
|
|
669
|
+
const out = service.formatComponent(component, ...rest);
|
|
670
|
+
return has.has(component?.uid) && out?.schema ? { ...out, schema: { ...out.schema, attributes: drop(out.schema.attributes) } } : out;
|
|
671
|
+
} }));
|
|
672
|
+
extend("plugin::content-type-builder.schema", (service) => ({ ...service, async getSchema(...args) {
|
|
673
|
+
const out = await service.getSchema(...args);
|
|
674
|
+
for (const uid of has) if (out?.components?.[uid]) out.components[uid] = { ...out.components[uid], attributes: drop(out.components[uid].attributes) };
|
|
675
|
+
return out;
|
|
676
|
+
} }));
|
|
677
|
+
}
|
|
478
678
|
function stripHidden(data, schema, schemaOf, name, depth = 0) {
|
|
479
679
|
if (!data || typeof data !== "object" || !schema || depth > 20) return data;
|
|
480
680
|
if (Array.isArray(data)) {
|
|
@@ -533,7 +733,7 @@ var require_hidden = __commonJS({
|
|
|
533
733
|
}
|
|
534
734
|
}));
|
|
535
735
|
}
|
|
536
|
-
module2.exports = { DEFAULT_NAME, hiddenName: hiddenName2, zoneComponents, injectHidden: injectHidden2, stripHidden, registerHiddenStrip: registerHiddenStrip2 };
|
|
736
|
+
module2.exports = { DEFAULT_NAME, hiddenName: hiddenName2, zoneComponents, injectHidden: injectHidden2, hideFromBuilder: hideFromBuilder2, stripHidden, registerHiddenStrip: registerHiddenStrip2 };
|
|
537
737
|
}
|
|
538
738
|
});
|
|
539
739
|
|
|
@@ -1485,12 +1685,13 @@ var require_history = __commonJS({
|
|
|
1485
1685
|
});
|
|
1486
1686
|
|
|
1487
1687
|
// server/index.js
|
|
1488
|
-
var { PLUGIN, TEMPLATES, TYPOLOGIES, DEFAULTS, catalog, validateSettings, validateFields, mergeSaved, layer, overrides, validatePrefs, mergePrefs, safeUrl, fail } = require_settings();
|
|
1489
|
-
var { safeGroups, validateGroups } = require_groups();
|
|
1490
|
-
var { hiddenName, injectHidden, registerHiddenStrip } = require_hidden();
|
|
1688
|
+
var { PLUGIN, TEMPLATES, TYPOLOGIES, DEFAULTS, catalog, validateSettings, validateFields, validateVariants, schemaMetadata, mergeSaved, layer, overrides, validatePrefs, mergePrefs, safeUrl, fail } = require_settings();
|
|
1689
|
+
var { safeGroups, validateGroups, layoutFields } = require_groups();
|
|
1690
|
+
var { hiddenName, injectHidden, hideFromBuilder, registerHiddenStrip } = require_hidden();
|
|
1491
1691
|
var { CRON, covers, eventContentType, historyService, historyController, registerHistory, registerPurge } = require_history();
|
|
1492
1692
|
var { trashContentType, trashService, trashController } = require_trash();
|
|
1493
1693
|
var STRAPI5 = false;
|
|
1694
|
+
var withHidden = [];
|
|
1494
1695
|
var store = (strapi) => strapi.store({ type: "plugin", name: PLUGIN });
|
|
1495
1696
|
var LEGACY_PLUGIN = "block-picker";
|
|
1496
1697
|
async function readSettings(strapi) {
|
|
@@ -1611,6 +1812,9 @@ module.exports = {
|
|
|
1611
1812
|
settings: null,
|
|
1612
1813
|
// Edit view field texts from code (never stored): { uid: { attribute: { label, description, placeholder } } }. See README "Field labels".
|
|
1613
1814
|
fields: null,
|
|
1815
|
+
// Other languages for the schema metadata (pluginOptions.blockscene, info.description), one flat map per locale:
|
|
1816
|
+
// { 'pt-BR': require('./blockscene/pt-BR.json') }. See README "Describing blocks and fields in the schema".
|
|
1817
|
+
translations: null,
|
|
1614
1818
|
// "Hide on the site": boolean attribute added to every Dynamic Zone component (a DB column); false adds nothing.
|
|
1615
1819
|
hiddenAttribute: "bsHidden"
|
|
1616
1820
|
},
|
|
@@ -1620,9 +1824,11 @@ module.exports = {
|
|
|
1620
1824
|
register({ strapi }) {
|
|
1621
1825
|
const plugin = strapi.plugin(PLUGIN);
|
|
1622
1826
|
const name = hiddenName(plugin.config("hiddenAttribute"));
|
|
1827
|
+
withHidden = [];
|
|
1623
1828
|
if (name === null) strapi.log.warn(`[${PLUGIN}] "hiddenAttribute" config ignored: expected a name like "bsHidden" or false. Hiding blocks is off.`);
|
|
1624
1829
|
if (!name) return;
|
|
1625
|
-
const { skipped } = injectHidden(strapi.components, strapi.contentTypes, name);
|
|
1830
|
+
const { added, skipped } = injectHidden(strapi.components, strapi.contentTypes, name);
|
|
1831
|
+
withHidden = added;
|
|
1626
1832
|
if (skipped.length) strapi.log.warn(`[${PLUGIN}] "${name}" already exists with another type on ${skipped.join(", ")}; those blocks cannot be hidden.`);
|
|
1627
1833
|
},
|
|
1628
1834
|
async bootstrap({ strapi }) {
|
|
@@ -1639,8 +1845,10 @@ module.exports = {
|
|
|
1639
1845
|
]);
|
|
1640
1846
|
strapi.plugin(PLUGIN).service("settings").projectDefaults();
|
|
1641
1847
|
strapi.plugin(PLUGIN).service("settings").fields();
|
|
1848
|
+
strapi.plugin(PLUGIN).service("settings").variants();
|
|
1642
1849
|
registerPublishGuard(strapi);
|
|
1643
1850
|
registerHiddenStrip(strapi, hiddenName(strapi.plugin(PLUGIN).config("hiddenAttribute")), strapi.plugin(PLUGIN));
|
|
1851
|
+
if (withHidden.length) hideFromBuilder(typeof strapi.get === "function" ? strapi.get("services") : strapi.container.get("services"), withHidden, hiddenName(strapi.plugin(PLUGIN).config("hiddenAttribute")));
|
|
1644
1852
|
if (STRAPI5) {
|
|
1645
1853
|
registerHistory(strapi);
|
|
1646
1854
|
registerPurge(strapi);
|
|
@@ -1658,33 +1866,53 @@ module.exports = {
|
|
|
1658
1866
|
const code = strapi.plugin(PLUGIN).config("settings");
|
|
1659
1867
|
project = null;
|
|
1660
1868
|
if (code) try {
|
|
1661
|
-
project = validateSettings(code, componentUids(strapi), contentTypeUids(strapi), apiUids(strapi));
|
|
1869
|
+
project = validateSettings(code, componentUids(strapi), contentTypeUids(strapi), apiUids(strapi), strapi.components);
|
|
1662
1870
|
} catch (error) {
|
|
1663
1871
|
strapi.log?.warn(`[${PLUGIN}] "settings" config ignored: ${error.message}. Using the built-in defaults under the saved settings.`);
|
|
1664
1872
|
}
|
|
1665
1873
|
return project;
|
|
1666
1874
|
};
|
|
1875
|
+
let meta;
|
|
1876
|
+
const schemaMeta = () => {
|
|
1877
|
+
if (meta !== void 0) return meta;
|
|
1878
|
+
const notes = [];
|
|
1879
|
+
meta = schemaMetadata({ ...strapi.contentTypes, ...strapi.components }, strapi.plugin(PLUGIN).config("translations"), notes);
|
|
1880
|
+
if (notes.length) strapi.log?.warn(`[${PLUGIN}] schema metadata left out: ${notes.slice(0, 20).join("; ")}${notes.length > 20 ? `; and ${notes.length - 20} more` : ""}.`);
|
|
1881
|
+
return meta;
|
|
1882
|
+
};
|
|
1667
1883
|
let fields;
|
|
1668
1884
|
const fieldTexts = () => {
|
|
1669
1885
|
if (fields !== void 0) return fields;
|
|
1670
1886
|
const schemas = Object.fromEntries(Object.entries({ ...strapi.contentTypes, ...strapi.components }).map(([uid, schema]) => [uid, Object.keys(schema?.attributes || {})]));
|
|
1671
1887
|
const stale = [];
|
|
1888
|
+
let code = {};
|
|
1672
1889
|
try {
|
|
1673
|
-
|
|
1890
|
+
code = validateFields(strapi.plugin(PLUGIN).config("fields"), schemas, stale);
|
|
1674
1891
|
} catch (error) {
|
|
1675
|
-
fields
|
|
1676
|
-
strapi.log?.warn(`[${PLUGIN}] "fields" config ignored: ${error.message}. Field labels fall back to the Content Manager's own.`);
|
|
1892
|
+
strapi.log?.warn(`[${PLUGIN}] "fields" config ignored: ${error.message}. Field labels fall back to the schema metadata and the Content Manager's own.`);
|
|
1677
1893
|
}
|
|
1678
1894
|
if (stale.length) strapi.log?.warn(`[${PLUGIN}] "fields" entries for fields the schema no longer has were skipped: ${stale.slice(0, 20).join(", ")}${stale.length > 20 ? ` and ${stale.length - 20} more` : ""}.`);
|
|
1895
|
+
fields = structuredClone(schemaMeta().fields);
|
|
1896
|
+
for (const [uid, entries] of Object.entries(code)) for (const [name, entry] of Object.entries(entries)) (fields[uid] ||= {})[name] = { ...fields[uid][name], ...entry };
|
|
1679
1897
|
return fields;
|
|
1680
1898
|
};
|
|
1681
|
-
|
|
1899
|
+
let variants;
|
|
1900
|
+
const insertVariants = () => {
|
|
1901
|
+
if (variants !== void 0) return variants;
|
|
1902
|
+
const notes = [];
|
|
1903
|
+
variants = validateVariants(strapi.plugin(PLUGIN).config("components"), strapi.components || {}, notes);
|
|
1904
|
+
for (const note of notes) strapi.log?.warn(`[${PLUGIN}] components variants: ${note}.`);
|
|
1905
|
+
return variants;
|
|
1906
|
+
};
|
|
1907
|
+
const get = async () => mergeSaved(layer(projectDefaults(), await readSettings(strapi)), componentUids(strapi), contentTypeUids(strapi), apiUids(strapi), strapi.components);
|
|
1682
1908
|
return {
|
|
1683
1909
|
projectDefaults,
|
|
1684
1910
|
get,
|
|
1685
1911
|
fields: fieldTexts,
|
|
1912
|
+
schema: schemaMeta,
|
|
1913
|
+
variants: insertVariants,
|
|
1686
1914
|
async set(value) {
|
|
1687
|
-
const next = validateSettings(value, componentUids(strapi), contentTypeUids(strapi), apiUids(strapi));
|
|
1915
|
+
const next = validateSettings(value, componentUids(strapi), contentTypeUids(strapi), apiUids(strapi), strapi.components);
|
|
1688
1916
|
for (const [uid, entry] of Object.entries(next.components)) {
|
|
1689
1917
|
if (entry.mediaId && !await findMedia(strapi, entry.mediaId).catch(() => null)) fail(`Media for "${uid}" does not exist`);
|
|
1690
1918
|
}
|
|
@@ -1711,10 +1939,12 @@ module.exports = {
|
|
|
1711
1939
|
blockPreview: plugin.config("blockPreview"),
|
|
1712
1940
|
groups: plugin.config("groups"),
|
|
1713
1941
|
componentUids: componentUids(strapi),
|
|
1714
|
-
schemas: strapi.components
|
|
1942
|
+
schemas: strapi.components,
|
|
1943
|
+
blocks: plugin.service("settings").schema().blocks
|
|
1715
1944
|
});
|
|
1716
1945
|
const settings = await plugin.service("settings").get();
|
|
1717
1946
|
const media = await resolveMedia(strapi, settings);
|
|
1947
|
+
for (const [uid, list] of Object.entries(plugin.service("settings").variants())) base.components[uid] = { ...base.components[uid], variants: list };
|
|
1718
1948
|
for (const [uid, entry] of Object.entries(settings.components)) {
|
|
1719
1949
|
base.components[uid] = {
|
|
1720
1950
|
...base.components[uid],
|
|
@@ -1727,8 +1957,10 @@ module.exports = {
|
|
|
1727
1957
|
const hidden = hiddenName(plugin.config("hiddenAttribute")) || null;
|
|
1728
1958
|
const types = Object.fromEntries(Object.entries(strapi.contentTypes || {}).filter(([uid]) => !uid.startsWith("admin::")).map(([uid, schema]) => [uid, [schema.info?.displayName || "", ...Object.keys(schema.attributes || {})]]));
|
|
1729
1959
|
const history = STRAPI5 && strapi.documents?.use && !base.disabled && settings.history.enabled ? { contentTypes: apiUids(strapi).filter((uid) => covers(settings.history, uid)) } : null;
|
|
1960
|
+
const layouts = Object.fromEntries(Object.entries(settings.components).filter(([uid, entry]) => entry.layout && base.groups?.[uid]).map(([uid, entry]) => [uid, entry.layout]));
|
|
1730
1961
|
ctx.body = {
|
|
1731
1962
|
...base,
|
|
1963
|
+
layouts,
|
|
1732
1964
|
palette: settings.palette,
|
|
1733
1965
|
contentTypes: settings.contentTypes,
|
|
1734
1966
|
hiddenAttribute: hidden,
|
|
@@ -1742,12 +1974,13 @@ module.exports = {
|
|
|
1742
1974
|
settings: ({ strapi }) => ({
|
|
1743
1975
|
async find(ctx) {
|
|
1744
1976
|
const settings = await strapi.plugin(PLUGIN).service("settings").get();
|
|
1745
|
-
const auto = catalog({ components: strapi.plugin(PLUGIN).config("components"), schemas: strapi.components }).components;
|
|
1977
|
+
const auto = catalog({ components: strapi.plugin(PLUGIN).config("components"), schemas: strapi.components, blocks: strapi.plugin(PLUGIN).service("settings").schema().blocks }).components;
|
|
1746
1978
|
const components = Object.entries(strapi.components || {}).map(([uid, schema]) => ({
|
|
1747
1979
|
uid,
|
|
1748
1980
|
displayName: schema.info?.displayName || uid,
|
|
1749
1981
|
category: schema.category || uid.split(".")[0],
|
|
1750
|
-
typology: auto[uid]?.typology
|
|
1982
|
+
typology: auto[uid]?.typology,
|
|
1983
|
+
layoutFields: layoutFields(schema)
|
|
1751
1984
|
}));
|
|
1752
1985
|
const contentTypes = Object.keys(contentTypeUids(strapi)).map((uid) => ({
|
|
1753
1986
|
uid,
|
package/package.json
CHANGED