@adobe/aio-cli-plugin-api-mesh 5.6.4 → 5.6.5-beta.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/aio-cli-plugin-api-mesh",
3
- "version": "5.6.4",
3
+ "version": "5.6.5-beta.1",
4
4
  "description": "Adobe I/O CLI plugin to develop and manage API mesh sources",
5
5
  "keywords": [
6
6
  "oclif-plugin"
@@ -0,0 +1,57 @@
1
+ /*
2
+ Copyright 2021 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const os = require('os');
15
+ const path = require('path');
16
+ const { readSecretsFile } = require('../../../serverUtils');
17
+ const { loadMeshSecrets } = require('../../../secrets');
18
+
19
+ describe('readSecretsFile', () => {
20
+ let tmp;
21
+ let prevCwd;
22
+
23
+ afterEach(() => {
24
+ if (prevCwd !== undefined) {
25
+ process.chdir(prevCwd);
26
+ prevCwd = undefined;
27
+ }
28
+ if (tmp) {
29
+ fs.rmSync(tmp, { recursive: true, force: true });
30
+ tmp = undefined;
31
+ }
32
+ });
33
+
34
+ test('parses JSON object strings in secrets.yaml like the tenant worker', () => {
35
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'readSecretsFile-test-'));
36
+ const meshDir = path.join(tmp, '.mesh');
37
+ fs.mkdirSync(meshDir, { recursive: true });
38
+ fs.writeFileSync(
39
+ path.join(meshDir, 'secrets.yaml'),
40
+ `TOKEN: '{"COMMERCE": "dummy-value"}'\nPLAIN: not-json\n`,
41
+ 'utf8',
42
+ );
43
+ prevCwd = process.cwd();
44
+ process.chdir(tmp);
45
+
46
+ const secrets = readSecretsFile('.mesh');
47
+
48
+ expect(secrets.TOKEN).toEqual({ COMMERCE: 'dummy-value' });
49
+ expect(secrets.PLAIN).toBe('not-json');
50
+
51
+ const mockLogger = { error: jest.fn() };
52
+ const asWorkerSees = loadMeshSecrets(mockLogger, JSON.stringify(secrets));
53
+ expect(asWorkerSees.TOKEN.COMMERCE).toBe('dummy-value');
54
+ expect(asWorkerSees.PLAIN).toBe('not-json');
55
+ expect(mockLogger.error).not.toHaveBeenCalled();
56
+ });
57
+ });
@@ -316,6 +316,31 @@ function ccDirectivesToString(directives) {
316
316
  return chStr.toString();
317
317
  }
318
318
 
319
+ /**
320
+ * Match production tenant-worker behavior: each bound secret value is JSON.parsed.
321
+ * YAML often leaves JSON blobs as strings; without this step, values like TOKEN: '{"COMMERCE": "dummy-value"}' stay broken locally.
322
+ *
323
+ * @param {Record<string, unknown>} secrets Parsed secrets object
324
+ * @returns {Record<string, unknown>}
325
+ */
326
+ function normalizeSecretsEnvValues(secrets) {
327
+ if (!secrets || typeof secrets !== 'object' || Array.isArray(secrets)) {
328
+ return secrets;
329
+ }
330
+ return Object.fromEntries(
331
+ Object.entries(secrets).map(([key, value]) => {
332
+ if (typeof value === 'string') {
333
+ try {
334
+ return [key, JSON.parse(value)];
335
+ } catch {
336
+ return [key, value];
337
+ }
338
+ }
339
+ return [key, value];
340
+ }),
341
+ );
342
+ }
343
+
319
344
  /**
320
345
  * Returns secrets content from artifacts
321
346
  * @param meshPath
@@ -326,7 +351,8 @@ function readSecretsFile(meshPath) {
326
351
  try {
327
352
  const filePath = path.resolve(process.cwd(), `${meshPath}`, 'secrets.yaml');
328
353
  if (fs.existsSync(filePath)) {
329
- secrets = YAML.parse(fs.readFileSync(filePath, 'utf8'));
354
+ const parsed = YAML.parse(fs.readFileSync(filePath, 'utf8'));
355
+ secrets = normalizeSecretsEnvValues(parsed || {});
330
356
  }
331
357
  } catch (error) {
332
358
  logger.error('Unexpected error: unable to locate secrets file in mesh artifacts.');