@aduptive/strapi-blockscene 2.0.0-alpha.12 → 2.0.0-alpha.14
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 +24 -8
- package/dist/admin.cjs +659 -147
- package/dist/admin.mjs +659 -147
- package/dist/server.cjs +50 -8
- package/package.json +1 -1
package/dist/server.cjs
CHANGED
|
@@ -108,8 +108,17 @@ var require_groups = __commonJS({
|
|
|
108
108
|
const start = rows.findIndex((row) => blockKey(row) === String(key));
|
|
109
109
|
if (start < 0 || !isOpener(rows[start], g)) return null;
|
|
110
110
|
const [, end] = groupRange(rows, start, g);
|
|
111
|
+
if (end <= start || uidOf(rows[end]) !== g[uidOf(rows[start])]) return null;
|
|
111
112
|
return [...rows.slice(0, start), ...rows.slice(end + 1)];
|
|
112
113
|
}
|
|
114
|
+
function unwrapGroup(rows, key, g) {
|
|
115
|
+
if (!g) return null;
|
|
116
|
+
const start = rows.findIndex((row) => blockKey(row) === String(key));
|
|
117
|
+
if (start < 0 || !isOpener(rows[start], g)) return null;
|
|
118
|
+
const [, end] = groupRange(rows, start, g);
|
|
119
|
+
if (end <= start || uidOf(rows[end]) !== g[uidOf(rows[start])]) return null;
|
|
120
|
+
return [...rows.slice(0, start), ...rows.slice(start + 1, end), ...rows.slice(end + 1)];
|
|
121
|
+
}
|
|
113
122
|
var MAX_COLUMNS = 12;
|
|
114
123
|
var parseColumns = (value) => {
|
|
115
124
|
const n = typeof value === "number" ? value : typeof value === "string" && /^\s*\d{1,3}\s*$/.test(value) ? Number(value) : NaN;
|
|
@@ -137,6 +146,7 @@ var require_groups = __commonJS({
|
|
|
137
146
|
topLevelRanges,
|
|
138
147
|
moveGroup,
|
|
139
148
|
removeGroup,
|
|
149
|
+
unwrapGroup,
|
|
140
150
|
blockKey,
|
|
141
151
|
isOpener,
|
|
142
152
|
isClose,
|
|
@@ -239,6 +249,13 @@ var require_settings = __commonJS({
|
|
|
239
249
|
var TAG = /^[^<>\n]{1,24}$/;
|
|
240
250
|
var cleanTags = (value) => Array.isArray(value) ? [...new Set(value.filter((tag) => typeof tag === "string" && TAG.test(tag.trim())).map((tag) => tag.trim()))].slice(0, 10) : [];
|
|
241
251
|
var validTags = (value) => Array.isArray(value) && value.length <= 10 && value.every((tag) => typeof tag === "string" && TAG.test(tag.trim()));
|
|
252
|
+
var directComponentUids = (contentTypes, perType = {}) => [...new Set(Object.entries(contentTypes || {}).filter(([uid]) => perType?.[uid]?.enabled !== false).flatMap(([, schema]) => Object.values(schema?.attributes || {}).filter((attr) => attr?.type === "dynamiczone").flatMap((attr) => attr.components || [])))];
|
|
253
|
+
var COMPONENT_CATEGORY = /^[a-z0-9][a-z0-9_-]{0,49}$/;
|
|
254
|
+
var safeComponentCategories2 = (value) => value == null ? null : Array.isArray(value) && value.length > 0 && value.length <= 50 && value.every((category) => typeof category === "string" && COMPONENT_CATEGORY.test(category)) ? [...new Set(value)] : null;
|
|
255
|
+
var settingsComponentUids2 = (contentTypes, components, perType = {}, categories = null) => {
|
|
256
|
+
const allowed = safeComponentCategories2(categories);
|
|
257
|
+
return directComponentUids(contentTypes, perType).filter((uid) => !allowed || allowed.includes(components?.[uid]?.category || uid.split(".")[0]));
|
|
258
|
+
};
|
|
242
259
|
var GUESSES = [
|
|
243
260
|
["hero", /hero|banner|cover/],
|
|
244
261
|
["text", /text|rich|quote|title/],
|
|
@@ -301,6 +318,7 @@ var require_settings = __commonJS({
|
|
|
301
318
|
["label", "description", "category", "keywords"].filter((key) => typeof entry[key] === "string").map((key) => [key, entry[key]])
|
|
302
319
|
);
|
|
303
320
|
entries[uid].image = safeUrl2(entry.image);
|
|
321
|
+
if (typeof entry.showRowThumbnail === "boolean") entries[uid].showRowThumbnail = entry.showRowThumbnail;
|
|
304
322
|
if (TYPOLOGIES2.includes(entry.typology)) entries[uid].typology = entry.typology;
|
|
305
323
|
const tags = cleanTags(entry.tags);
|
|
306
324
|
if (tags.length || entries[uid].category) entries[uid].tags = tags.length ? tags : cleanTags([entries[uid].category]);
|
|
@@ -358,6 +376,9 @@ var require_settings = __commonJS({
|
|
|
358
376
|
} else if (key === "mediaId") {
|
|
359
377
|
if (!Number.isInteger(entry.mediaId) || entry.mediaId <= 0) fail2(`Invalid media for "${uid}"`);
|
|
360
378
|
clean.mediaId = entry.mediaId;
|
|
379
|
+
} else if (key === "showRowThumbnail") {
|
|
380
|
+
if (typeof entry.showRowThumbnail !== "boolean") fail2(`Invalid row thumbnail setting for "${uid}"`);
|
|
381
|
+
clean.showRowThumbnail = entry.showRowThumbnail;
|
|
361
382
|
} else if (key === "layout") {
|
|
362
383
|
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`);
|
|
363
384
|
clean.layout = structuredClone(entry.layout);
|
|
@@ -416,6 +437,7 @@ var require_settings = __commonJS({
|
|
|
416
437
|
clean.tags = cleanTags(clean.tags);
|
|
417
438
|
if (!clean.tags.length) delete clean.tags;
|
|
418
439
|
}
|
|
440
|
+
if ("showRowThumbnail" in clean && typeof clean.showRowThumbnail !== "boolean") delete clean.showRowThumbnail;
|
|
419
441
|
if ("layout" in clean && !validLayout(clean.layout, schemas && (schemas[uid]?.attributes || {}))) delete clean.layout;
|
|
420
442
|
if (Object.keys(clean).length) out.components[uid] = clean;
|
|
421
443
|
}
|
|
@@ -732,7 +754,7 @@ var require_settings = __commonJS({
|
|
|
732
754
|
return out;
|
|
733
755
|
}
|
|
734
756
|
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) : []]));
|
|
735
|
-
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, validateKits: validateKits2, schemaMetadata: schemaMetadata2, mergeSaved: mergeSaved2, layer: layer2, overrides: overrides2, safeUrl: safeUrl2, fail: fail2 };
|
|
757
|
+
module2.exports = { PLUGIN: PLUGIN2, HIDDEN_MODES, TEMPLATES: TEMPLATES2, TYPOLOGIES: TYPOLOGIES2, guessTypology, facetsOf, directComponentUids, settingsComponentUids: settingsComponentUids2, safeComponentCategories: safeComponentCategories2, validatePrefs: validatePrefs2, mergePrefs: mergePrefs2, ICONS, DEFAULTS: DEFAULTS2, catalog: catalog2, validateSettings: validateSettings2, validateFields: validateFields2, validateVariants: validateVariants2, validateKits: validateKits2, schemaMetadata: schemaMetadata2, mergeSaved: mergeSaved2, layer: layer2, overrides: overrides2, safeUrl: safeUrl2, fail: fail2 };
|
|
736
758
|
}
|
|
737
759
|
});
|
|
738
760
|
|
|
@@ -1438,6 +1460,18 @@ var require_history = __commonJS({
|
|
|
1438
1460
|
var hashOf = (text) => createHash("sha256").update(text).digest("hex");
|
|
1439
1461
|
var covers2 = (history, uid) => Boolean(history?.enabled) && uid.startsWith("api::") && (history.contentTypes === "all" || Array.isArray(history.contentTypes) && history.contentTypes.includes(uid));
|
|
1440
1462
|
var retention = ({ retentionDays, eventDays }, now = Date.now()) => ({ snapshotsBefore: new Date(now - retentionDays * DAY), eventsBefore: new Date(now - eventDays * DAY) });
|
|
1463
|
+
var hasChanges = (summary) => Boolean(summary?.initial || summary?.fields?.length || ["added", "removed", "changed"].some((key) => summary?.blocks?.[key] > 0));
|
|
1464
|
+
function collapseVersions(events) {
|
|
1465
|
+
const versions = [];
|
|
1466
|
+
for (const event of events) {
|
|
1467
|
+
const previous = versions[versions.length - 1];
|
|
1468
|
+
if (event.hash && previous?.hash === event.hash) {
|
|
1469
|
+
if (!previous.actions.includes(event.action)) previous.actions.push(event.action);
|
|
1470
|
+
if (!hasChanges(previous.summary) && hasChanges(event.summary)) previous.summary = event.summary;
|
|
1471
|
+
} else versions.push({ ...event, actions: [event.action] });
|
|
1472
|
+
}
|
|
1473
|
+
return versions;
|
|
1474
|
+
}
|
|
1441
1475
|
function actorOf(strapi) {
|
|
1442
1476
|
let ctx;
|
|
1443
1477
|
try {
|
|
@@ -1539,12 +1573,14 @@ var require_history = __commonJS({
|
|
|
1539
1573
|
async list({ uid, documentId, locale, actor = "", page = 1, pageSize = 25 }) {
|
|
1540
1574
|
const scope2 = { contentType: uid, relatedDocumentId: documentId, locale: locale || null };
|
|
1541
1575
|
const where = { ...scope2, ...actor && { actor } };
|
|
1542
|
-
const [
|
|
1543
|
-
events().findMany({ select: ["id", "action", "actor", "actorName", "at", "summary", "hash", "size"], where, orderBy: [{ at: "desc" }, { id: "desc" }]
|
|
1576
|
+
const [timeline, kept, people] = await Promise.all([
|
|
1577
|
+
events().findMany({ select: ["id", "action", "actor", "actorName", "at", "summary", "hash", "size"], where, orderBy: [{ at: "desc" }, { id: "desc" }] }),
|
|
1544
1578
|
events().findMany({ select: ["hash"], where: { ...scope2, size: { $gt: 0 } } }),
|
|
1545
|
-
events().count({ where }),
|
|
1546
1579
|
events().findMany({ select: ["actor", "actorName"], where: scope2, orderBy: [{ at: "desc" }, { id: "desc" }] })
|
|
1547
1580
|
]);
|
|
1581
|
+
const versions = collapseVersions(timeline);
|
|
1582
|
+
const total = versions.length;
|
|
1583
|
+
const list = versions.slice((page - 1) * pageSize, page * pageSize);
|
|
1548
1584
|
const hashes = new Set(kept.map((row) => row.hash));
|
|
1549
1585
|
const actors2 = [...new Map(people.slice().reverse().map(({ actor: actor2, actorName }) => [actor2, { actor: actor2, actorName }])).values()];
|
|
1550
1586
|
return {
|
|
@@ -1792,12 +1828,12 @@ var require_history = __commonJS({
|
|
|
1792
1828
|
};
|
|
1793
1829
|
}
|
|
1794
1830
|
});
|
|
1795
|
-
module2.exports = { EVENT_UID, ACTIONS, CAPTURED, CRON: CRON2, BATCH, eventContentType: eventContentType2, covers: covers2, retention, actorOf, refsOf, can, readableTypes, historyService: historyService2, registerHistory: registerHistory2, registerPurge: registerPurge2, historyController: historyController2 };
|
|
1831
|
+
module2.exports = { EVENT_UID, ACTIONS, CAPTURED, CRON: CRON2, BATCH, eventContentType: eventContentType2, covers: covers2, retention, actorOf, refsOf, collapseVersions, can, readableTypes, historyService: historyService2, registerHistory: registerHistory2, registerPurge: registerPurge2, historyController: historyController2 };
|
|
1796
1832
|
}
|
|
1797
1833
|
});
|
|
1798
1834
|
|
|
1799
1835
|
// server/index.js
|
|
1800
|
-
var { PLUGIN, TEMPLATES, TYPOLOGIES, DEFAULTS, catalog, validateSettings, validateFields, validateVariants, validateKits, schemaMetadata, mergeSaved, layer, overrides, validatePrefs, mergePrefs, safeUrl, fail } = require_settings();
|
|
1836
|
+
var { PLUGIN, TEMPLATES, TYPOLOGIES, DEFAULTS, catalog, settingsComponentUids, safeComponentCategories, validateSettings, validateFields, validateVariants, validateKits, schemaMetadata, mergeSaved, layer, overrides, validatePrefs, mergePrefs, safeUrl, fail } = require_settings();
|
|
1801
1837
|
var { safeGroups, validateGroups, invalidComponents, layoutFields } = require_groups();
|
|
1802
1838
|
var { hiddenName, injectHidden, hideFromBuilder, registerHiddenStrip } = require_hidden();
|
|
1803
1839
|
var { CRON, covers, eventContentType, historyService, historyController, registerHistory, registerPurge } = require_history();
|
|
@@ -1945,6 +1981,9 @@ module.exports = {
|
|
|
1945
1981
|
// Optional layout groups: OPEN component uid -> its CLOSE uid, e.g. { 'wrappers.join': 'wrappers.close' }.
|
|
1946
1982
|
// Empty/absent: every Dynamic Zone component is an ordinary block. See README "Layout groups".
|
|
1947
1983
|
groups: null,
|
|
1984
|
+
// Optional Strapi component categories shown as configurable cards in Settings > Block gallery.
|
|
1985
|
+
// This does not change the components allowed by each Dynamic Zone.
|
|
1986
|
+
settingsComponentCategories: null,
|
|
1948
1987
|
// Project defaults from code: same shape as the stored settings, e.g. require('./blockscene.json'). See README "Settings page".
|
|
1949
1988
|
settings: null,
|
|
1950
1989
|
// Edit view field texts from code (never stored): { uid: { attribute: { label, description, placeholder } } }. See README "Field labels".
|
|
@@ -1965,6 +2004,7 @@ module.exports = {
|
|
|
1965
2004
|
const name = hiddenName(plugin.config("hiddenAttribute"));
|
|
1966
2005
|
withHidden = [];
|
|
1967
2006
|
if (name === null) strapi.log.warn(`[${PLUGIN}] "hiddenAttribute" config ignored: expected a name like "bsHidden" or false. Hiding blocks is off.`);
|
|
2007
|
+
if (plugin.config("settingsComponentCategories") != null && !safeComponentCategories(plugin.config("settingsComponentCategories"))) strapi.log.warn(`[${PLUGIN}] "settingsComponentCategories" config ignored: expected 1 to 50 Strapi component category names.`);
|
|
1968
2008
|
if (!name) return;
|
|
1969
2009
|
const { added, skipped } = injectHidden(strapi.components, strapi.contentTypes, name);
|
|
1970
2010
|
withHidden = added;
|
|
@@ -2100,7 +2140,8 @@ module.exports = {
|
|
|
2100
2140
|
...media[uid],
|
|
2101
2141
|
template: entry.template,
|
|
2102
2142
|
...entry.typology && { typology: entry.typology },
|
|
2103
|
-
...entry.tags && { tags: entry.tags }
|
|
2143
|
+
...entry.tags && { tags: entry.tags },
|
|
2144
|
+
...typeof entry.showRowThumbnail === "boolean" && { showRowThumbnail: entry.showRowThumbnail }
|
|
2104
2145
|
};
|
|
2105
2146
|
}
|
|
2106
2147
|
const hidden = hiddenName(plugin.config("hiddenAttribute")) || null;
|
|
@@ -2125,7 +2166,8 @@ module.exports = {
|
|
|
2125
2166
|
async find(ctx) {
|
|
2126
2167
|
const settings = await strapi.plugin(PLUGIN).service("settings").get();
|
|
2127
2168
|
const auto = catalog({ components: strapi.plugin(PLUGIN).config("components"), schemas: strapi.components, blocks: strapi.plugin(PLUGIN).service("settings").schema().blocks }).components;
|
|
2128
|
-
const
|
|
2169
|
+
const visible = new Set(settingsComponentUids(strapi.contentTypes, strapi.components, settings.contentTypes, strapi.plugin(PLUGIN).config("settingsComponentCategories")));
|
|
2170
|
+
const components = Object.entries(strapi.components || {}).filter(([uid]) => visible.has(uid)).map(([uid, schema]) => ({
|
|
2129
2171
|
uid,
|
|
2130
2172
|
displayName: schema.info?.displayName || uid,
|
|
2131
2173
|
category: schema.category || uid.split(".")[0],
|
package/package.json
CHANGED