@aduptive/strapi-blockscene 2.0.0-alpha.12 → 2.0.0-alpha.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/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
 
@@ -1797,7 +1819,7 @@ var require_history = __commonJS({
1797
1819
  });
1798
1820
 
1799
1821
  // server/index.js
1800
- var { PLUGIN, TEMPLATES, TYPOLOGIES, DEFAULTS, catalog, validateSettings, validateFields, validateVariants, validateKits, schemaMetadata, mergeSaved, layer, overrides, validatePrefs, mergePrefs, safeUrl, fail } = require_settings();
1822
+ var { PLUGIN, TEMPLATES, TYPOLOGIES, DEFAULTS, catalog, settingsComponentUids, safeComponentCategories, validateSettings, validateFields, validateVariants, validateKits, schemaMetadata, mergeSaved, layer, overrides, validatePrefs, mergePrefs, safeUrl, fail } = require_settings();
1801
1823
  var { safeGroups, validateGroups, invalidComponents, layoutFields } = require_groups();
1802
1824
  var { hiddenName, injectHidden, hideFromBuilder, registerHiddenStrip } = require_hidden();
1803
1825
  var { CRON, covers, eventContentType, historyService, historyController, registerHistory, registerPurge } = require_history();
@@ -1945,6 +1967,9 @@ module.exports = {
1945
1967
  // Optional layout groups: OPEN component uid -> its CLOSE uid, e.g. { 'wrappers.join': 'wrappers.close' }.
1946
1968
  // Empty/absent: every Dynamic Zone component is an ordinary block. See README "Layout groups".
1947
1969
  groups: null,
1970
+ // Optional Strapi component categories shown as configurable cards in Settings > Block gallery.
1971
+ // This does not change the components allowed by each Dynamic Zone.
1972
+ settingsComponentCategories: null,
1948
1973
  // Project defaults from code: same shape as the stored settings, e.g. require('./blockscene.json'). See README "Settings page".
1949
1974
  settings: null,
1950
1975
  // Edit view field texts from code (never stored): { uid: { attribute: { label, description, placeholder } } }. See README "Field labels".
@@ -1965,6 +1990,7 @@ module.exports = {
1965
1990
  const name = hiddenName(plugin.config("hiddenAttribute"));
1966
1991
  withHidden = [];
1967
1992
  if (name === null) strapi.log.warn(`[${PLUGIN}] "hiddenAttribute" config ignored: expected a name like "bsHidden" or false. Hiding blocks is off.`);
1993
+ 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
1994
  if (!name) return;
1969
1995
  const { added, skipped } = injectHidden(strapi.components, strapi.contentTypes, name);
1970
1996
  withHidden = added;
@@ -2100,7 +2126,8 @@ module.exports = {
2100
2126
  ...media[uid],
2101
2127
  template: entry.template,
2102
2128
  ...entry.typology && { typology: entry.typology },
2103
- ...entry.tags && { tags: entry.tags }
2129
+ ...entry.tags && { tags: entry.tags },
2130
+ ...typeof entry.showRowThumbnail === "boolean" && { showRowThumbnail: entry.showRowThumbnail }
2104
2131
  };
2105
2132
  }
2106
2133
  const hidden = hiddenName(plugin.config("hiddenAttribute")) || null;
@@ -2125,7 +2152,8 @@ module.exports = {
2125
2152
  async find(ctx) {
2126
2153
  const settings = await strapi.plugin(PLUGIN).service("settings").get();
2127
2154
  const auto = catalog({ components: strapi.plugin(PLUGIN).config("components"), schemas: strapi.components, blocks: strapi.plugin(PLUGIN).service("settings").schema().blocks }).components;
2128
- const components = Object.entries(strapi.components || {}).map(([uid, schema]) => ({
2155
+ const visible = new Set(settingsComponentUids(strapi.contentTypes, strapi.components, settings.contentTypes, strapi.plugin(PLUGIN).config("settingsComponentCategories")));
2156
+ const components = Object.entries(strapi.components || {}).filter(([uid]) => visible.has(uid)).map(([uid, schema]) => ({
2129
2157
  uid,
2130
2158
  displayName: schema.info?.displayName || uid,
2131
2159
  category: schema.category || uid.split(".")[0],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aduptive/strapi-blockscene",
3
- "version": "2.0.0-alpha.12",
3
+ "version": "2.0.0-alpha.13",
4
4
  "description": "Visual component gallery for native Strapi dynamic zones.",
5
5
  "license": "MIT",
6
6
  "author": "Andrea Scarpello <aduptive@gmail.com>",