@adobe/helix-config 5.6.9 → 5.6.10

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.6.10](https://github.com/adobe/helix-config/compare/v5.6.9...v5.6.10) (2025-11-05)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * merge secretIds and apiKeyIds ([#333](https://github.com/adobe/helix-config/issues/333)) ([bb96631](https://github.com/adobe/helix-config/commit/bb966319e7e6a58ec6c5005e65277eacc991eeff))
7
+
1
8
  ## [5.6.9](https://github.com/adobe/helix-config/compare/v5.6.8...v5.6.9) (2025-10-24)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-config",
3
- "version": "5.6.9",
3
+ "version": "5.6.10",
4
4
  "description": "Helix Config",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -35,20 +35,20 @@
35
35
  "reporter-options": "configFile=.mocha-multi.json"
36
36
  },
37
37
  "devDependencies": {
38
- "@adobe/eslint-config-helix": "3.0.12",
39
- "@eslint/config-helpers": "0.4.0",
38
+ "@adobe/eslint-config-helix": "3.0.13",
39
+ "@eslint/config-helpers": "0.4.1",
40
40
  "@semantic-release/changelog": "6.0.3",
41
41
  "@semantic-release/git": "10.0.1",
42
- "@semantic-release/npm": "13.0.0",
42
+ "@semantic-release/npm": "13.1.1",
43
43
  "c8": "10.1.3",
44
44
  "eslint": "9.4.0",
45
45
  "husky": "9.1.7",
46
46
  "junit-report-builder": "5.1.1",
47
- "lint-staged": "16.2.3",
47
+ "lint-staged": "16.2.5",
48
48
  "mocha": "11.7.4",
49
49
  "mocha-multi-reporters": "1.5.1",
50
50
  "mocha-suppress-logs": "0.6.0",
51
- "semantic-release": "25.0.0"
51
+ "semantic-release": "25.0.1"
52
52
  },
53
53
  "lint-staged": {
54
54
  "*.js": "eslint",
@@ -14,17 +14,10 @@ import {
14
14
  } from './ConfigContext.js';
15
15
  import { ConfigObject } from './config-object.js';
16
16
  import { contentConfigMerge } from './legacy-config-merge.js';
17
- import { prune } from './utils.js';
17
+ import { prune, toArray } from './utils.js';
18
18
 
19
19
  const HELIX_CODE_BUS = 'helix-code-bus';
20
20
 
21
- export function toArray(v) {
22
- if (!v) {
23
- return [];
24
- }
25
- return Array.isArray(v) ? v : [v];
26
- }
27
-
28
21
  /**
29
22
  * Retrieves the helix-config.json which is an aggregate from fstab.yaml and head.html.
30
23
  *
@@ -18,8 +18,10 @@ import {
18
18
  SCOPE_DELIVERY,
19
19
  SCOPE_RAW, SCOPE_PUBLIC,
20
20
  } from './ConfigContext.js';
21
- import { resolveLegacyConfig, fetchRobotsTxt, toArray } from './config-legacy.js';
22
- import { deepGetOrCreate, prune } from './utils.js';
21
+ import { resolveLegacyConfig, fetchRobotsTxt } from './config-legacy.js';
22
+ import {
23
+ canonicalArrayString, deepGetOrCreate, prune, uniqueArray,
24
+ } from './utils.js';
23
25
  import { ConfigObject } from './config-object.js';
24
26
  import { ModifiersConfig } from './ModifiersConfig.js';
25
27
  import { StatusCodeError } from './status-code-error.js';
@@ -61,23 +63,6 @@ const VALID_ORG_SCOPES = [
61
63
  SCOPE_ADMIN,
62
64
  ];
63
65
 
64
- /**
65
- * Creates a string representation of the given array that is suitable for substring matching by
66
- * delimiting each entry with `,` eg: ,foo@adobe.com,bar@adobe.com,
67
- * @param {object} root object
68
- * @param {string} partition property partition
69
- * @param {string} prop name of the property
70
- * @returns {string}
71
- */
72
- export function canonicalArrayString(root, partition, prop) {
73
- const value = root?.[partition]?.[prop];
74
- if (!value || value.length === 0) {
75
- return '';
76
- }
77
- value.sort((s1, s2) => s1.localeCompare(s2));
78
- return `,${value.join(',')},`;
79
- }
80
-
81
66
  /**
82
67
  * Returns the hash of the global delivery token if defined.
83
68
  * @param ctx
@@ -122,6 +107,7 @@ async function getGlobalTokenHash(ctx, rso) {
122
107
  * @returns {string|null}
123
108
  */
124
109
  function lookupSecret(config, orgConfig, id, hashed = false) {
110
+ /* c8 ignore next 3 */
125
111
  if (!id) {
126
112
  return null;
127
113
  }
@@ -162,11 +148,18 @@ function resolveSecret(object, idProp, dstProp, siteConfig, orgConfig) {
162
148
  */
163
149
  export async function getAccessConfig(ctx, config, orgConfig, partition, rso) {
164
150
  const { access = {} } = config;
151
+ // get the (legacy) apiKeyIds or secretIds from the partition specific config
165
152
  const pAccess = access[partition] ?? {};
166
- const secretId = toArray(
167
- pAccess.apiKeyId ?? pAccess.secretId ?? access.site?.apiKeyId ?? access.site?.secretId,
168
- );
169
- const allow = toArray(pAccess.allow ?? access.site?.allow);
153
+ let secretId = uniqueArray(pAccess.apiKeyId, pAccess.secretId);
154
+ if (secretId.length === 0) {
155
+ // if empty, also check the access.site configs
156
+ secretId = uniqueArray(access.site?.apiKeyId, access.site?.secretId);
157
+ }
158
+ // same for 'allow'
159
+ let allow = uniqueArray(pAccess.allow);
160
+ if (allow.length === 0) {
161
+ allow = uniqueArray(access.site?.allow);
162
+ }
170
163
  const cfg = {
171
164
  secretId,
172
165
  allow,
@@ -334,6 +327,8 @@ async function resolveConfig(ctx, rso, scope) {
334
327
  preview: await loadMetadata(ctx, config, 'preview'),
335
328
  live: await loadMetadata(ctx, config, 'live'),
336
329
  };
330
+ }
331
+ if (scope === SCOPE_PIPELINE || scope === SCOPE_RAW) {
337
332
  if (!config.robots) {
338
333
  ctx.timer?.update('robots-txt');
339
334
  const robots = await fetchRobotsTxt(ctx, config.code.owner, config.code.repo);
@@ -341,8 +336,6 @@ async function resolveConfig(ctx, rso, scope) {
341
336
  config.robots = robots;
342
337
  }
343
338
  }
344
- }
345
- if (scope === SCOPE_PIPELINE || scope === SCOPE_DELIVERY) {
346
339
  ctx.timer?.update('head.html');
347
340
  config.head = await loadHeadHtml(ctx, config, rso.ref);
348
341
  }
package/src/utils.js CHANGED
@@ -60,3 +60,53 @@ export function prune(obj, path = '') {
60
60
  }
61
61
  return obj;
62
62
  }
63
+
64
+ /**
65
+ * Creates a string representation of the given array that is suitable for substring matching by
66
+ * delimiting each entry with `,` eg: ,foo@adobe.com,bar@adobe.com,
67
+ * @param {object} root object
68
+ * @param {string} partition property partition
69
+ * @param {string} prop name of the property
70
+ * @returns {string}
71
+ */
72
+ export function canonicalArrayString(root, partition, prop) {
73
+ const value = root?.[partition]?.[prop];
74
+ if (!value || value.length === 0) {
75
+ return '';
76
+ }
77
+ value.sort((s1, s2) => s1.localeCompare(s2));
78
+ return `,${value.join(',')},`;
79
+ }
80
+
81
+ /**
82
+ * wraps the given value in an array if not already one.
83
+ * @param v
84
+ * @returns {*|*[]}
85
+ */
86
+ export function toArray(v) {
87
+ if (!v) {
88
+ return [];
89
+ }
90
+ return Array.isArray(v) ? v : [v];
91
+ }
92
+
93
+ /**
94
+ * Creates a unique, sorted array of the given arguments. array arguments are unzipped, undefined or
95
+ * null arguments are skipped
96
+ * @param from
97
+ * @returns {any[]}
98
+ */
99
+ export function uniqueArray(...from) {
100
+ const res = new Set();
101
+ const traverse = (v) => {
102
+ if (Array.isArray(v)) {
103
+ for (const e of v) {
104
+ traverse(e);
105
+ }
106
+ } else if (v !== null && v !== undefined && v !== '') {
107
+ res.add(v);
108
+ }
109
+ };
110
+ traverse(from);
111
+ return Array.from(res.values()).sort();
112
+ }