@adobe/helix-config 5.4.7 → 5.4.8

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 CHANGED
@@ -1,3 +1,10 @@
1
+ ## [5.4.8](https://github.com/adobe/helix-config/compare/v5.4.7...v5.4.8) (2025-06-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * load user group sheets dynamically ([#295](https://github.com/adobe/helix-config/issues/295)) ([3327e02](https://github.com/adobe/helix-config/commit/3327e0249d7329146982b315ed1c79cdcc102994)), closes [#292](https://github.com/adobe/helix-config/issues/292)
7
+
1
8
  ## [5.4.7](https://github.com/adobe/helix-config/compare/v5.4.6...v5.4.7) (2025-06-15)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-config",
3
- "version": "5.4.7",
3
+ "version": "5.4.8",
4
4
  "description": "Helix Config",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -35,8 +35,8 @@
35
35
  "reporter-options": "configFile=.mocha-multi.json"
36
36
  },
37
37
  "devDependencies": {
38
- "@adobe/eslint-config-helix": "3.0.3",
39
- "@eslint/config-helpers": "0.2.2",
38
+ "@adobe/eslint-config-helix": "3.0.5",
39
+ "@eslint/config-helpers": "0.2.3",
40
40
  "@semantic-release/changelog": "6.0.3",
41
41
  "@semantic-release/git": "10.0.1",
42
42
  "@semantic-release/npm": "12.0.1",
@@ -44,8 +44,8 @@
44
44
  "eslint": "9.4.0",
45
45
  "husky": "9.1.7",
46
46
  "junit-report-builder": "5.1.1",
47
- "lint-staged": "16.1.0",
48
- "mocha": "11.6.0",
47
+ "lint-staged": "16.1.2",
48
+ "mocha": "11.7.0",
49
49
  "mocha-multi-reporters": "1.5.1",
50
50
  "mocha-suppress-logs": "0.5.1",
51
51
  "nock": "13.5.6",
@@ -394,13 +394,35 @@ function resolveGroup(groups, name) {
394
394
  return users.map((user) => user.email);
395
395
  }
396
396
 
397
+ async function loadGroup(ctx, siteConfig, path) {
398
+ const { contentBusId } = siteConfig.data.content;
399
+ const key = `${contentBusId}/preview/${path}`;
400
+ const res = await ctx.loader.getObject(HELIX_CONTENT_BUS, key);
401
+ if (!res.body) {
402
+ ctx.log.info('referenced user sheet does not exist: %s', key);
403
+ return [];
404
+ }
405
+ siteConfig.updateLastModified(res.headers);
406
+
407
+ // return users
408
+ const users = JSON.parse(res.body);
409
+ if (!users.default?.data?.length) {
410
+ ctx.log.info('referenced user sheet is empty: %s', key);
411
+ return [];
412
+ }
413
+ ctx.log.info('loaded user sheet from %s. %d users', key, users.default.data.length);
414
+ return users.default.data.map((row) => ModifiersConfig.toLowerKeys(row).user);
415
+ }
416
+
397
417
  /**
398
418
  * Compute the access.admin.role arrays for the admin config. Resolves site and org groups.
419
+ * @param ctx
420
+ * @param siteConfig
399
421
  * @param admin
400
422
  * @param orgConfig
401
423
  * @param configGroups
402
424
  */
403
- function computeSiteAdminRoles(admin, orgConfig, configGroups = {}) {
425
+ async function computeSiteAdminRoles(ctx, siteConfig, admin, orgConfig, configGroups = {}) {
404
426
  const {
405
427
  users: orgUsers = [],
406
428
  groups: orgGroups = {},
@@ -412,15 +434,20 @@ function computeSiteAdminRoles(admin, orgConfig, configGroups = {}) {
412
434
  if (entry.indexOf('@') > 0) {
413
435
  users.add(entry);
414
436
  } else if (entry.startsWith('groups/')) {
415
- // keep entry in list so that admin can auto-migrate updates to the groups json
416
- // TODO: remove after v4 EOL
417
- users.add(entry);
418
437
  const reference = entry.endsWith('.json')
419
438
  ? entry.substring(7, entry.length - 5)
420
439
  : entry.substring(7);
421
440
  for (const email of resolveGroup(configGroups, reference)) {
422
441
  users.add(email);
423
442
  }
443
+ // load users dynamically as well
444
+ // eslint-disable-next-line no-await-in-loop
445
+ const group = await loadGroup(ctx, siteConfig, `.helix/${reference}.json`);
446
+ for (const email of group) {
447
+ users.add(email);
448
+ }
449
+ // add entry in list so that admin can purge the config when modified
450
+ users.add(`/.helix/${reference}.json`);
424
451
  } else if (entry.startsWith('/groups/')) {
425
452
  const reference = entry.endsWith('.json')
426
453
  ? entry.substring(8, entry.length - 5)
@@ -428,6 +455,17 @@ function computeSiteAdminRoles(admin, orgConfig, configGroups = {}) {
428
455
  for (const email of resolveGroup(orgGroups, reference)) {
429
456
  users.add(email);
430
457
  }
458
+ } else if (entry.startsWith('/')) {
459
+ const reference = entry.endsWith('.json')
460
+ ? entry.substring(1)
461
+ : `${entry.substring(1)}.json`;
462
+ // eslint-disable-next-line no-await-in-loop
463
+ const group = await loadGroup(ctx, siteConfig, reference);
464
+ for (const email of group) {
465
+ users.add(email);
466
+ }
467
+ // add entry in list so that admin can purge the config when modified
468
+ users.add(`/${reference}`);
431
469
  }
432
470
  }
433
471
  roles[roleName] = Array.from(users);
@@ -507,7 +545,7 @@ export async function getConfigResponse(ctx, opts) {
507
545
  };
508
546
  if (opts.scope === SCOPE_ADMIN || opts.scope === SCOPE_RAW) {
509
547
  // eslint-disable-next-line max-len
510
- config.access.admin = computeSiteAdminRoles(admin, orgConfig, config.groups);
548
+ config.access.admin = await computeSiteAdminRoles(ctx, siteConfig, admin, orgConfig, config.groups);
511
549
  }
512
550
  prune(config.access);
513
551
  if (!Object.keys(config.access).length) {