@adobe/aio-cli-plugin-api-mesh 3.6.0 → 3.6.1-beta.2

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.
@@ -1 +1 @@
1
- {"version":"3.6.0","commands":{"PLUGINNAME":{"id":"PLUGINNAME","description":"Your description here","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio PLUGINNAME:some_command"],"flags":{"someflag":{"name":"someflag","type":"option","char":"f","description":"this is some flag"}},"args":[]},"api-mesh:create":{"id":"api-mesh:create","description":"Create a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"},"secrets":{"name":"secrets","type":"option","char":"s","description":"Path to secrets file","default":false}},"args":[{"name":"file"}]},"api-mesh:delete":{"id":"api-mesh:delete","description":"Delete the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false}},"args":[]},"api-mesh:describe":{"id":"api-mesh:describe","description":"Get details of a mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:get":{"id":"api-mesh:get","description":"Get the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false}},"args":[{"name":"file"}]},"api-mesh:init":{"id":"api-mesh:init","description":"This command will create a workspace where you can organise your API mesh configuration and other files","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":[{"description":"API mesh workspace init","command":"aio api-mesh init commerce-mesh"},{"description":"API mesh workspace init with flags","command":"aio api-mesh init commerce-mesh --path ./mesh_projects/test_mesh --git y --packageManager yarn"}],"flags":{"path":{"name":"path","type":"option","char":"p","default":"."},"packageManager":{"name":"packageManager","type":"option","char":"m","options":["npm","yarn"]},"git":{"name":"git","type":"option","char":"g","options":["y","n"]}},"args":[{"name":"projectName","description":"Project name","required":true}]},"api-mesh:run":{"id":"api-mesh:run","description":"Run a local development server that builds and compiles a mesh locally","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":[],"flags":{"port":{"name":"port","type":"option","char":"p","description":"Port number for the local dev server"},"debug":{"name":"debug","type":"boolean","description":"Enable debugging mode","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"select":{"name":"select","type":"boolean","description":"Retrieve existing artifacts from the mesh","allowNo":false},"secrets":{"name":"secrets","type":"option","char":"s","description":"Path to secrets file","default":false}},"args":[{"name":"file","description":"Mesh File"}]},"api-mesh:status":{"id":"api-mesh:status","description":"Get a mesh status with a given meshid.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:update":{"id":"api-mesh:update","description":"Update a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"},"secrets":{"name":"secrets","type":"option","char":"s","description":"Path to secrets file","default":false}},"args":[{"name":"file"}]},"api-mesh:source:discover":{"id":"api-mesh:source:discover","description":"Return the list of avaliable sources","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm install action prompt. CLI will not check ask user to install source.","allowNo":false}},"args":[]},"api-mesh:source:get":{"id":"api-mesh:source:get","description":"Command returns the content of a specific source.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:get -s=<version>@<source_name>","$ aio api-mesh:source:get -s<source_name>","$ aio api-mesh:source:get -m"],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm print action prompt. CLI will not check ask user to print source.","allowNo":false},"source":{"name":"source","type":"option","char":"s","description":"Source name"},"multiple":{"name":"multiple","type":"boolean","char":"m","description":"Select multiple sources","allowNo":false}},"args":[]},"api-mesh:source:install":{"id":"api-mesh:source:install","description":"Command to install the source to your API mesh.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:install <version>@<source_name>","$ aio api-mesh:source:install <source_name> -v <variable_name>=<variable_value>","$ aio api-mesh:source:install <source_name> -f <path_to_variables_file>"],"flags":{"source":{"name":"source","type":"option","char":"s","description":"Source name"},"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm override action prompt. CLI will not check ask user to override source.","allowNo":false},"variable":{"name":"variable","type":"option","char":"v","description":"Variables required for the source"},"variable-file":{"name":"variable-file","type":"option","char":"f","description":"Variables file path"},"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[{"name":"source"}]}}}
1
+ {"version":"3.6.1-beta.2","commands":{"PLUGINNAME":{"id":"PLUGINNAME","description":"Your description here","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio PLUGINNAME:some_command"],"flags":{"someflag":{"name":"someflag","type":"option","char":"f","description":"this is some flag"}},"args":[]},"api-mesh:create":{"id":"api-mesh:create","description":"Create a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"},"secrets":{"name":"secrets","type":"option","char":"s","description":"Path to secrets file","default":false}},"args":[{"name":"file"}]},"api-mesh:delete":{"id":"api-mesh:delete","description":"Delete the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false}},"args":[]},"api-mesh:describe":{"id":"api-mesh:describe","description":"Get details of a mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:get":{"id":"api-mesh:get","description":"Get the config of a given mesh","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"json":{"name":"json","type":"boolean","description":"Output JSON","allowNo":false}},"args":[{"name":"file"}]},"api-mesh:init":{"id":"api-mesh:init","description":"This command will create a workspace where you can organise your API mesh configuration and other files","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":[{"description":"API mesh workspace init","command":"aio api-mesh init commerce-mesh"},{"description":"API mesh workspace init with flags","command":"aio api-mesh init commerce-mesh --path ./mesh_projects/test_mesh --git y --packageManager yarn"}],"flags":{"path":{"name":"path","type":"option","char":"p","default":"."},"packageManager":{"name":"packageManager","type":"option","char":"m","options":["npm","yarn"]},"git":{"name":"git","type":"option","char":"g","options":["y","n"]}},"args":[{"name":"projectName","description":"Project name","required":true}]},"api-mesh:run":{"id":"api-mesh:run","description":"Run a local development server that builds and compiles a mesh locally","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":[],"flags":{"port":{"name":"port","type":"option","char":"p","description":"Port number for the local dev server"},"debug":{"name":"debug","type":"boolean","description":"Enable debugging mode","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"select":{"name":"select","type":"boolean","description":"Retrieve existing artifacts from the mesh","allowNo":false},"secrets":{"name":"secrets","type":"option","char":"s","description":"Path to secrets file","default":false}},"args":[{"name":"file","description":"Mesh File"}]},"api-mesh:status":{"id":"api-mesh:status","description":"Get a mesh status with a given meshid.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[]},"api-mesh:update":{"id":"api-mesh:update","description":"Update a mesh with the given config.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false},"autoConfirmAction":{"name":"autoConfirmAction","type":"boolean","char":"c","description":"Auto confirm action prompt. CLI will not check for user approval before executing the action.","allowNo":false},"env":{"name":"env","type":"option","char":"e","description":"Path to env file","default":".env"},"secrets":{"name":"secrets","type":"option","char":"s","description":"Path to secrets file","default":false}},"args":[{"name":"file"}]},"api-mesh:source:discover":{"id":"api-mesh:source:discover","description":"Return the list of avaliable sources","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm install action prompt. CLI will not check ask user to install source.","allowNo":false}},"args":[]},"api-mesh:source:get":{"id":"api-mesh:source:get","description":"Command returns the content of a specific source.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:get -s=<version>@<source_name>","$ aio api-mesh:source:get -s<source_name>","$ aio api-mesh:source:get -m"],"flags":{"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm print action prompt. CLI will not check ask user to print source.","allowNo":false},"source":{"name":"source","type":"option","char":"s","description":"Source name"},"multiple":{"name":"multiple","type":"boolean","char":"m","description":"Select multiple sources","allowNo":false}},"args":[]},"api-mesh:source:install":{"id":"api-mesh:source:install","description":"Command to install the source to your API mesh.","pluginName":"@adobe/aio-cli-plugin-api-mesh","pluginType":"core","aliases":[],"examples":["$ aio api-mesh:source:install <version>@<source_name>","$ aio api-mesh:source:install <source_name> -v <variable_name>=<variable_value>","$ aio api-mesh:source:install <source_name> -f <path_to_variables_file>"],"flags":{"source":{"name":"source","type":"option","char":"s","description":"Source name"},"confirm":{"name":"confirm","type":"boolean","char":"c","description":"Auto confirm override action prompt. CLI will not check ask user to override source.","allowNo":false},"variable":{"name":"variable","type":"option","char":"v","description":"Variables required for the source"},"variable-file":{"name":"variable-file","type":"option","char":"f","description":"Variables file path"},"ignoreCache":{"name":"ignoreCache","type":"boolean","char":"i","description":"Ignore cache and force manual org -> project -> workspace selection","allowNo":false}},"args":[{"name":"source"}]}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/aio-cli-plugin-api-mesh",
3
- "version": "3.6.0",
3
+ "version": "3.6.1-beta.2",
4
4
  "description": "Adobe I/O CLI plugin to develop and manage API mesh sources",
5
5
  "keywords": [
6
6
  "oclif-plugin"
@@ -38,11 +38,11 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@adobe-apimesh/mesh-builder": "1.6.0",
41
- "@adobe/aio-cli-lib-console": "^4.0.0",
42
- "@adobe/aio-lib-core-config": "^3.0.0",
43
- "@adobe/aio-lib-core-logging": "^2.0.0",
44
- "@adobe/aio-lib-env": "^2.0.0",
45
- "@adobe/aio-lib-ims": "^6.0.1",
41
+ "@adobe/aio-cli-lib-console": "^5.0.0",
42
+ "@adobe/aio-lib-core-config": "^5.0.0",
43
+ "@adobe/aio-lib-core-logging": "^3.0.0",
44
+ "@adobe/aio-lib-env": "^3.0.0",
45
+ "@adobe/aio-lib-ims": "^7.0.1",
46
46
  "@adobe/plugin-hooks": "0.3.0",
47
47
  "@adobe/plugin-on-fetch": "0.1.0",
48
48
  "@graphql-mesh/cli": "0.82.30",
@@ -94,7 +94,8 @@
94
94
  "source-registry-storage-adapter": "github:devx-services/source-registry-storage-adapter#main",
95
95
  "util": "^0.12.5",
96
96
  "uuid": "^8.3.2",
97
- "yaml": "^2.4.2"
97
+ "yaml": "^2.4.2",
98
+ "newrelic": "^11.0.0"
98
99
  },
99
100
  "devDependencies": {
100
101
  "@babel/eslint-parser": "^7.15.8",
@@ -0,0 +1,21 @@
1
+ {
2
+ "meshConfig": {
3
+ "sources": [
4
+ {
5
+ "name": "Commerce",
6
+ "handler": {
7
+ "graphql": {
8
+ "endpoint": "https://venia.magento.com/graphql",
9
+ "operationHeaders": {
10
+ "secretHome1": "{context.secrets.Home}",
11
+ "secretHome2": "{context.secrets.HomeString}",
12
+ "secretHome3": "{context.secrets.HomeWithSlash}",
13
+ "secretHome4": "{context.secrets.HomeStringWithSlash}"
14
+ },
15
+ "useGETForQueries": true
16
+ }
17
+ }
18
+ }
19
+ ]
20
+ }
21
+ }
@@ -0,0 +1,4 @@
1
+ Home: $HOME
2
+ HomeString: \$HOME
3
+ HomeWithSlash: \\$HOME
4
+ HomeStringWithSlash: \\\$HOME
@@ -57,6 +57,12 @@ jest.mock('@adobe-apimesh/mesh-builder', () => {
57
57
  };
58
58
  });
59
59
 
60
+ jest.mock('envsub/js/envsub-parser', () => {
61
+ return contents => {
62
+ return contents.replaceAll('$HOME', 'rootPath');
63
+ };
64
+ });
65
+
60
66
  let logSpy = null;
61
67
  let errorLogSpy = null;
62
68
  let parseSpy = null;
@@ -975,4 +981,21 @@ describe('run command tests', () => {
975
981
  expect(writeSecretsFile).toHaveBeenCalled();
976
982
  expect(startGraphqlServer).toHaveBeenCalledWith(expect.anything(), defaultPort, false);
977
983
  });
984
+
985
+ test('should escape variables that are preceded by backslash symbol', async () => {
986
+ parseSpy.mockResolvedValueOnce({
987
+ args: { file: 'src/commands/__fixtures__/sample_mesh_with_escaped_secrets.json' },
988
+ flags: {
989
+ secrets: 'src/commands/__fixtures__/secrets_with_escaped_variables.yaml',
990
+ debug: false,
991
+ },
992
+ });
993
+
994
+ await RunCommand.run();
995
+ expect(writeSecretsFile).toHaveBeenCalledWith(
996
+ 'Home: rootPath\nHomeString: $HOME\nHomeWithSlash: \\rootPath\nHomeStringWithSlash: \\$HOME\n',
997
+ expect.anything(),
998
+ );
999
+ expect(startGraphqlServer).toHaveBeenCalledWith(expect.anything(), defaultPort, false);
1000
+ });
978
1001
  });
@@ -104,7 +104,7 @@ class InitCommand extends Command {
104
104
  const githubWorkflowPath = `${getAppRootDir()}/src/templates/deployWorkflow.yaml`;
105
105
  const readmePath = `${getAppRootDir()}/src/templates/readme.md`;
106
106
  const sampleMeshConfigPath = `${getAppRootDir()}/src/templates/mesh.json`;
107
-
107
+ const newRelicConfigPath = `${getAppRootDir()}/src/templates/newrelic.cjs`;
108
108
  const shouldCreateWorkspace = await promptConfirm(
109
109
  `Do you want to create the workspace in ${absolutePath}`,
110
110
  );
@@ -170,6 +170,7 @@ class InitCommand extends Command {
170
170
  await this.cloneFile(sampleENVPath, `${absolutePath}/.env`);
171
171
  await this.cloneFile(readmePath, `${absolutePath}/README.md`);
172
172
  await this.cloneFile(sampleMeshConfigPath, `${absolutePath}/mesh.json`);
173
+ await this.cloneFile(newRelicConfigPath, `${absolutePath}/newrelic.cjs`);
173
174
 
174
175
  this.log(`Installing dependencies`);
175
176
 
package/src/server.js CHANGED
@@ -52,6 +52,24 @@ const getCORSOptions = () => {
52
52
  }
53
53
  };
54
54
 
55
+ // Custom get secrets handler
56
+ const getSecretsHandler = {
57
+ get: function (target, prop, receiver) {
58
+ if (prop === 'toJSON') {
59
+ // Handle the toJSON case
60
+ return () => target;
61
+ }
62
+ if (prop in target) {
63
+ return Reflect.get(target, prop, receiver);
64
+ } else {
65
+ throw new Error(`The secret ${String(prop)} is not available.`);
66
+ }
67
+ },
68
+ set: function () {
69
+ throw new Error('Setting secrets is not allowed');
70
+ },
71
+ };
72
+
55
73
  const getYogaServer = async () => {
56
74
  if (yogaServer) {
57
75
  return yogaServer;
@@ -67,6 +85,8 @@ const getYogaServer = async () => {
67
85
 
68
86
  const secrets = readSecretsFile(meshId);
69
87
 
88
+ const secretsProxy = new Proxy(secrets, getSecretsHandler);
89
+
70
90
  logger.info('Creating graphQL server');
71
91
 
72
92
  meshConfig = readMeshConfig(meshId);
@@ -78,7 +98,7 @@ const getYogaServer = async () => {
78
98
  cors: corsOptions,
79
99
  context: initialContext => ({
80
100
  ...initialContext,
81
- secrets,
101
+ secrets: secretsProxy,
82
102
  }),
83
103
  });
84
104
 
@@ -0,0 +1,9 @@
1
+ exports.config = {
2
+ agent_enabled: false,
3
+ logging: {
4
+ enabled: false,
5
+ },
6
+ error_collector: {
7
+ enabled: false,
8
+ },
9
+ };
@@ -26,7 +26,7 @@
26
26
  "@graphql-mesh/soap": "0.14.25",
27
27
  "@graphql-mesh/http": "^0.96.9",
28
28
  "graphql": "^16.6.0",
29
- "@adobe/plugin-hooks": "^0.1.0",
29
+ "@adobe/plugin-hooks": "0.3.0",
30
30
  "@adobe/plugin-on-fetch": "^0.1.0",
31
31
  "eslint-plugin-no-loops": "^0.3.0",
32
32
  "eslint-plugin-node": "^11.1.0",
package/src/utils.js CHANGED
@@ -406,8 +406,12 @@ async function parseSecrets(secretsContent) {
406
406
  },
407
407
  cli: false,
408
408
  };
409
- const compiledSecretsFileContent = parseEnv(secretsContent, envParserConfig);
409
+
410
+ const { secrets: newSecretsContent, placeholderMap } = replaceEscapedVariables(secretsContent);
411
+ const compiledContent = parseEnv(newSecretsContent, envParserConfig);
412
+ const compiledSecretsFileContent = replacePlaceholders(compiledContent, placeholderMap);
410
413
  const parsedSecrets = YAML.parse(compiledSecretsFileContent);
414
+
411
415
  //check if secrets file is empty
412
416
  if (!parsedSecrets) {
413
417
  throw new Error(chalk.red('Invalid YAML file contents. Please verify and try again.'));
@@ -477,6 +481,59 @@ async function encryptSecrets(publicKey, secrets) {
477
481
  }
478
482
  }
479
483
 
484
+ // Function to replace escaped variables with placeholders
485
+ const replaceEscapedVariables = content => {
486
+ const placeholderMap = {};
487
+ const escapeDollarRegex = /\\+[$](([a-zA-Z]+)|([{][a-zA-Z]+[}]))/g;
488
+ const newContent = content.replace(escapeDollarRegex, matched => {
489
+ const slashCount = (matched.match(/\\/g) || []).length;
490
+ if (slashCount % 2 !== 0) {
491
+ const placeholder = `__PLACEHOLDER_${Math.random().toString(36).substr(2, 9)}__`;
492
+ const newValue = reduceConsecutiveBackslashes(matched);
493
+ placeholderMap[placeholder] = newValue;
494
+ return placeholder;
495
+ } else {
496
+ return reduceConsecutiveBackslashes(matched);
497
+ }
498
+ });
499
+ return {
500
+ secrets: newContent,
501
+ placeholderMap,
502
+ };
503
+ };
504
+
505
+ // Function to replace placeholders back with original variables
506
+ const replacePlaceholders = (content, placeholderMap) => {
507
+ let newContent = content;
508
+ for (const [key, value] of Object.entries(placeholderMap)) {
509
+ newContent = newContent.replaceAll(key, value);
510
+ }
511
+ return newContent;
512
+ };
513
+
514
+ // Function to reduce the backslashes
515
+ function reduceConsecutiveBackslashes(str) {
516
+ let result = '';
517
+ let i = 0;
518
+
519
+ while (i < str.length) {
520
+ if (str[i] === '\\') {
521
+ let count = 0;
522
+ // Count consecutive backslashes
523
+ while (i < str.length && str[i] === '\\') {
524
+ count++;
525
+ i++;
526
+ }
527
+ // Append half the count of backslashes (rounded down)
528
+ result += '\\'.repeat(Math.floor(count / 2));
529
+ } else {
530
+ result += str[i];
531
+ i++;
532
+ }
533
+ }
534
+ return result;
535
+ }
536
+
480
537
  module.exports = {
481
538
  ignoreCacheFlag,
482
539
  autoConfirmActionFlag,