@catladder/cli 0.0.0-refactor-resolve-references-next-de1019aa → 0.0.0-refactor-resolve-references-next-c8f614f7

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.
Files changed (39) hide show
  1. package/dist/bundles/catenv/index.js +185 -28
  2. package/dist/bundles/cli/index.js +183 -24
  3. package/dist/cli/src/apps/catenv/printVariables.js.map +1 -1
  4. package/dist/cli/src/apps/catenv/types.d.ts +0 -2
  5. package/dist/cli/src/apps/catenv/utils.d.ts +2 -2
  6. package/dist/cli/src/apps/catenv/utils.js +2 -3
  7. package/dist/cli/src/apps/catenv/utils.js.map +1 -1
  8. package/dist/cli/src/apps/catenv/writeDotEnvFiles.js +0 -1
  9. package/dist/cli/src/apps/catenv/writeDotEnvFiles.js.map +1 -1
  10. package/dist/cli/src/config/getProjectConfig.d.ts +3 -3
  11. package/dist/cli/src/config/getProjectConfig.js.map +1 -1
  12. package/dist/pipeline/src/bash/bashEscape.d.ts +23 -3
  13. package/dist/pipeline/src/bash/bashEscape.js +108 -11
  14. package/dist/pipeline/src/bash/bashEscape.js.map +1 -1
  15. package/dist/pipeline/src/bash/bashYaml.js +2 -1
  16. package/dist/pipeline/src/bash/bashYaml.js.map +1 -1
  17. package/dist/pipeline/src/bash/getInjectVarsScript.js +5 -1
  18. package/dist/pipeline/src/bash/getInjectVarsScript.js.map +1 -1
  19. package/dist/pipeline/src/build/base/writeDotEnv.js +4 -5
  20. package/dist/pipeline/src/build/base/writeDotEnv.js.map +1 -1
  21. package/dist/pipeline/src/globalScriptFunctions/index.d.ts +14 -0
  22. package/dist/pipeline/src/globalScriptFunctions/index.js +32 -0
  23. package/dist/pipeline/src/globalScriptFunctions/index.js.map +1 -0
  24. package/dist/pipeline/src/pipeline/gitlab/createGitlabPipeline.d.ts +1 -1
  25. package/dist/pipeline/src/pipeline/gitlab/createGitlabPipeline.js +6 -1
  26. package/dist/pipeline/src/pipeline/gitlab/createGitlabPipeline.js.map +1 -1
  27. package/dist/pipeline/src/types/gitlab-types.d.ts +1 -0
  28. package/dist/pipeline/src/utils/gitlab.js +10 -2
  29. package/dist/pipeline/src/utils/gitlab.js.map +1 -1
  30. package/dist/pipeline/src/variables/VariableValueContainingReferences.d.ts +3 -5
  31. package/dist/pipeline/src/variables/VariableValueContainingReferences.js +8 -2
  32. package/dist/pipeline/src/variables/VariableValueContainingReferences.js.map +1 -1
  33. package/dist/tsconfig.tsbuildinfo +1 -1
  34. package/package.json +1 -1
  35. package/src/apps/catenv/printVariables.ts +2 -2
  36. package/src/apps/catenv/types.ts +0 -2
  37. package/src/apps/catenv/utils.ts +8 -7
  38. package/src/apps/catenv/writeDotEnvFiles.ts +0 -1
  39. package/src/config/getProjectConfig.ts +1 -1
@@ -113,9 +113,8 @@ const getCurrentComponentAndEnvFromChoice = async (config, choice) => {
113
113
  };
114
114
  exports.getCurrentComponentAndEnvFromChoice = getCurrentComponentAndEnvFromChoice;
115
115
  const makeKeyValueString = (variables, keyPrefix = "") => Object.entries(variables)
116
- .map(
117
- // double quotes seems not to work
118
- ([key, value]) => `${keyPrefix}${key}='${(0, pipeline_1.bashEscape)(value, "single")}'`)
116
+ // quotes are important, otherwise line breaks don't work properly
117
+ .map(([key, value]) => `${keyPrefix}${key}=${(0, pipeline_1.escapeForDotEnv)(value)}`)
119
118
  .join("\n");
120
119
  exports.makeKeyValueString = makeKeyValueString;
121
120
  const sanitizeEnvVarName = (name) => name.replace(/[\s\-.]+/g, "_");
@@ -152,7 +151,6 @@ const writeDotEnvFiles = async (config, choice) => {
152
151
  delete variables["_ALL_ENV_VAR_KEYS"];
153
152
  const componentDir = (0, utils_1.getComponentFullPath)(gitRoot, config, componentName);
154
153
  const filePath = (0, path_1.join)(componentDir, ".env");
155
- // many .dotenv don't like multiline values, so we sanitize them here
156
154
  await (0, pipeline_1.writeGeneratedFile)(filePath, (0, utils_1.makeKeyValueString)(variables), {
157
155
  commentChar: "#",
158
156
  });
@@ -827,35 +825,132 @@ exports.joinBashExpressions = joinBashExpressions;
827
825
  "use strict";
828
826
 
829
827
  Object.defineProperty(exports, "__esModule", ({ value: true }));
830
- exports.escapeSingleQuotes = exports.escapeDoubleQuotes = exports.escapeString = exports.bashEscape = void 0;
828
+ exports.escapeForDotEnv = exports.escapeSingleQuotes = exports.escapeDoubleQuotes = exports.escapeBashExpression = exports.escapeString = exports.bashEscape = void 0;
829
+ const globalScriptFunctions_1 = __nccwpck_require__(2912);
831
830
  const VariableValueContainingReferences_1 = __nccwpck_require__(1592);
832
831
  const BashExpression_1 = __nccwpck_require__(2376);
833
832
  /**
834
833
  * escapes a string or bash expression for bash
835
834
  * it either can escape single or double quotes (double is default)
836
835
  */
837
- const bashEscape = (value, mode = "double") => {
836
+ const bashEscape = (value, options = {
837
+ quotes: "double",
838
+ }) => {
838
839
  if (value instanceof BashExpression_1.BashExpression) {
839
- return value.toString(); // no need to escape bash expressions, as we want them to evaluate
840
+ // no need to escape
841
+ return (0, exports.escapeBashExpression)(value, options);
840
842
  }
841
843
  if (value instanceof VariableValueContainingReferences_1.VariableValueContainingReferences) {
842
- return value.toString({
843
- escape: mode,
844
- });
844
+ return value.toString(options);
845
845
  }
846
- return (0, exports.escapeString)(value, mode);
846
+ return (0, exports.escapeString)(value, options);
847
847
  };
848
848
  exports.bashEscape = bashEscape;
849
- const escapeString = (value, mode = "double") => {
850
- return mode === "double"
851
- ? (0, exports.escapeDoubleQuotes)(value)
852
- : (0, exports.escapeSingleQuotes)(value);
849
+ const escapeString = (value, { quotes } = {
850
+ quotes: "double",
851
+ }) => {
852
+ const quoteEscaped = quotes
853
+ ? quotes === "single"
854
+ ? (0, exports.escapeSingleQuotes)(value)
855
+ : (0, exports.escapeDoubleQuotes)(value)
856
+ : value;
857
+ return quoteEscaped;
853
858
  };
854
859
  exports.escapeString = escapeString;
860
+ const escapeBashExpression = (value, options) => {
861
+ // no need to escape, we just return the string
862
+ return value;
863
+ };
864
+ exports.escapeBashExpression = escapeBashExpression;
855
865
  const escapeDoubleQuotes = (value) => value === null || value === void 0 ? void 0 : value.toString().replace(/"/g, '\\"');
856
866
  exports.escapeDoubleQuotes = escapeDoubleQuotes;
857
867
  const escapeSingleQuotes = (value) => value === null || value === void 0 ? void 0 : value.toString().replace(/'/g, "\\'");
858
868
  exports.escapeSingleQuotes = escapeSingleQuotes;
869
+ /**
870
+ *
871
+ * what an absolute nightmare.
872
+ * unfortunatly, dotenv has many limitations. You can't escape quotes properly.
873
+ *
874
+ * In order to be very forgiving, we need to do some magic here:
875
+ *
876
+ * - when the value contains no newlines, we are fine
877
+ * - if the value contains newlines, we need to wrap it in quotes. And thats where the problem begins:
878
+ * - you can't escape quotes. this is a shitty limitation of dotenv and node
879
+ * - you can have inner quotes, but they break in node.js (not in dotenv though), see https://github.com/nodejs/node/issues/54134
880
+ * - so we need to quote cleverly
881
+ * - to make things worse, we need to check whether we have a simple stirng or a bash expression, that needs to be evalulated first...
882
+ */
883
+ const escapeForDotEnv = (value) => {
884
+ if (value === undefined || value === null) {
885
+ return "";
886
+ }
887
+ if (typeof value === "string") {
888
+ // if string contains newlines, we need to wrap it in quotes
889
+ // we additionaly escape newlines, that give best compatibility
890
+ if (value.includes("\n")) {
891
+ const newlinesReplaces = value.replace(/\n/g, "\\n");
892
+ // default to ", but if this is not possible, we try to use ' or `
893
+ const quote = value.includes(`"`)
894
+ ? value.includes(`'`)
895
+ ? value.includes("`")
896
+ ? // If all quote types are present, default to no
897
+ ""
898
+ : "`"
899
+ : "'"
900
+ : '"';
901
+ // if we found a quote, we can wrap the string in it
902
+ return `${quote}${newlinesReplaces}${quote}`;
903
+ }
904
+ else {
905
+ // otherwise we can return as is
906
+ return value;
907
+ }
908
+ }
909
+ else if (value instanceof BashExpression_1.BashExpression) {
910
+ return escapeBashExpressionForDotEnv(value);
911
+ }
912
+ else if (value instanceof VariableValueContainingReferences_1.VariableValueContainingReferences) {
913
+ // instead of doing it part-wise, we just do it all at once
914
+ const containsAnyBashExpression = value.parts.some((part) => part instanceof BashExpression_1.BashExpression);
915
+ if (!containsAnyBashExpression) {
916
+ return (0, exports.escapeForDotEnv)(value.toString({
917
+ quotes: "double",
918
+ }));
919
+ }
920
+ else {
921
+ const result = escapeBashExpressionForDotEnv(new BashExpression_1.BashExpression(value.toString({
922
+ quotes: "double",
923
+ })));
924
+ return result;
925
+ }
926
+ }
927
+ else {
928
+ return value;
929
+ }
930
+ };
931
+ exports.escapeForDotEnv = escapeForDotEnv;
932
+ // basically the same thing as above for bash
933
+ // thx chatgpt for this
934
+ const escapeForDotEnvScript = (0, globalScriptFunctions_1.registerGlobalScriptFunction)("escapeForDotEnv", `
935
+ input="\${1:-$(cat)}"
936
+ input="\${input//$'\\n'/\\\\n}"
937
+ if [[ "$input" == *\\\\n* ]]; then
938
+ if [[ "$input" == *\\"* && "$input" == *\\'* && "$input" == *\\\`* ]]; then
939
+ printf "%s\\n" "$input"
940
+ elif [[ "$input" == *\\"* && "$input" == *\\'* ]]; then
941
+ printf "\`%s\`\\n" "$input"
942
+ elif [[ "$input" == *\\"* ]]; then
943
+ printf "'%s'\\n" "$input"
944
+ else
945
+ printf "\\"%s\\"\\n" "$input"
946
+ fi
947
+ else
948
+ printf "%s\\n" "$input"
949
+ fi
950
+ `);
951
+ const escapeBashExpressionForDotEnv = (value) => {
952
+ return value.transformWithCommand(escapeForDotEnvScript.name).toString();
953
+ };
859
954
  //# sourceMappingURL=bashEscape.js.map
860
955
 
861
956
  /***/ }),
@@ -917,7 +1012,8 @@ const variableContainingReferences = {
917
1012
  const stringified = value.parts
918
1013
  .map((part) => part instanceof BashExpression_1.BashExpression
919
1014
  ? indentNewlinesInBashExpression(part, ctx.indent)
920
- : part.toString().replace(/\n/g, `\n${ctx.indent}`))
1015
+ : // indent every new line
1016
+ part.toString().replace(/\n/g, `\n${ctx.indent}`))
921
1017
  .join("");
922
1018
  return "|-\n" + ctx.indent + stringified;
923
1019
  },
@@ -969,7 +1065,11 @@ const getInjectVarsScript = (vars) => {
969
1065
  // filter out null and undefined values
970
1066
  return Object.entries(vars)
971
1067
  .filter(([, value]) => !(0, lodash_1.isNil)(value))
972
- .map(([key, value]) => `export ${key}="${value ? (0, bashEscape_1.bashEscape)(value) : ""}"`);
1068
+ .map(([key, value]) => `export ${key}="${value
1069
+ ? (0, bashEscape_1.bashEscape)(value, {
1070
+ quotes: "double",
1071
+ })
1072
+ : ""}"`);
973
1073
  };
974
1074
  exports.getInjectVarsScript = getInjectVarsScript;
975
1075
  //# sourceMappingURL=getInjectVarsScript.js.map
@@ -1292,9 +1392,9 @@ exports.writeBuildInfo = writeBuildInfo;
1292
1392
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1293
1393
  exports.componentContextNeedsBuildTimeDotEnv = exports.writeDotEnv = void 0;
1294
1394
  const lodash_1 = __nccwpck_require__(3255);
1295
- const gitlab_1 = __nccwpck_require__(8490);
1296
- const getBuildInfoVariables_1 = __nccwpck_require__(7827);
1297
1395
  const bashEscape_1 = __nccwpck_require__(2463);
1396
+ const getBuildInfoVariables_1 = __nccwpck_require__(7827);
1397
+ const gitlab_1 = __nccwpck_require__(8490);
1298
1398
  /**
1299
1399
  * writes a .env file in the components folder
1300
1400
  * @param context
@@ -1309,10 +1409,9 @@ const writeDotEnv = (context) => {
1309
1409
  // filter out build variables, since they may interfer with caching like turbo
1310
1410
  // build variables are rarely used anyway and we may treat them differently in the future
1311
1411
  .filter(([key]) => !getBuildInfoVariables_1.ALL_BUILD_VARIABLES.includes(key))
1312
- // double quotes seems not to work in some cases
1313
- .map(([key, value]) => `${key}='${(0, bashEscape_1.bashEscape)(value, "single")}'`)
1412
+ .map(([key, value]) => `${key}=${(0, bashEscape_1.escapeForDotEnv)(value)}`)
1314
1413
  .join("\n");
1315
- return (0, gitlab_1.collapseableSection)("write-dotenv-" + context.name, "write dot env")([
1414
+ return (0, gitlab_1.collapseableSection)("write-dotenv-" + context.name, "write dot env for " + context.name)([
1316
1415
  `cat <<EOF > ${context.build.dir}/.env
1317
1416
  ${keyValueString}
1318
1417
  EOF`,
@@ -5194,6 +5293,45 @@ exports.contextIsStoppable = contextIsStoppable;
5194
5293
 
5195
5294
  /***/ }),
5196
5295
 
5296
+ /***/ 2912:
5297
+ /***/ ((__unused_webpack_module, exports) => {
5298
+
5299
+ "use strict";
5300
+
5301
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5302
+ exports.registerGlobalScriptFunction = exports.globalScriptFunctions = void 0;
5303
+ class GlobalScriptFunction {
5304
+ constructor(name, script) {
5305
+ this.name = name;
5306
+ this.script = script;
5307
+ }
5308
+ toBashFunction() {
5309
+ return `function ${this.name} () {
5310
+ ${this.script.trim()}
5311
+ }`.trim();
5312
+ }
5313
+ invoke(...args) {
5314
+ return `${this.name} ${args.join(" ")}`;
5315
+ }
5316
+ }
5317
+ exports.globalScriptFunctions = new Map();
5318
+ /**
5319
+ * registers a global script function
5320
+ * only use that in top-level scopes as it will attach the function to the global scope
5321
+ */
5322
+ const registerGlobalScriptFunction = (name, script) => {
5323
+ if (exports.globalScriptFunctions.has(name)) {
5324
+ throw new Error(`Global script function ${name} already exists`);
5325
+ }
5326
+ const scriptFunction = new GlobalScriptFunction(name, script);
5327
+ exports.globalScriptFunctions.set(name, scriptFunction);
5328
+ return scriptFunction;
5329
+ };
5330
+ exports.registerGlobalScriptFunction = registerGlobalScriptFunction;
5331
+ //# sourceMappingURL=index.js.map
5332
+
5333
+ /***/ }),
5334
+
5197
5335
  /***/ 603:
5198
5336
  /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
5199
5337
 
@@ -5822,7 +5960,8 @@ function getGitlabNeedsForWorkspaceJob(context, { needsStages, needs }, allJobs)
5822
5960
  Object.defineProperty(exports, "__esModule", ({ value: true }));
5823
5961
  exports.createGitlabPipelineWithDefaults = void 0;
5824
5962
  const runner_1 = __nccwpck_require__(4058);
5825
- const createGitlabPipelineWithDefaults = ({ image, variables, ...config }) => {
5963
+ const globalScriptFunctions_1 = __nccwpck_require__(2912);
5964
+ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, ...config }) => {
5826
5965
  return {
5827
5966
  image: image !== null && image !== void 0 ? image : (0, runner_1.getRunnerImage)("jobs-default"), // default image
5828
5967
  variables: {
@@ -5833,6 +5972,10 @@ const createGitlabPipelineWithDefaults = ({ image, variables, ...config }) => {
5833
5972
  GIT_DEPTH: "1", // no need the full depth
5834
5973
  ...(variables !== null && variables !== void 0 ? variables : {}),
5835
5974
  },
5975
+ before_script: [
5976
+ ...[...globalScriptFunctions_1.globalScriptFunctions.values()].map((script) => script.toBashFunction()),
5977
+ ...(before_script !== null && before_script !== void 0 ? before_script : []),
5978
+ ],
5836
5979
  ...config,
5837
5980
  };
5838
5981
  };
@@ -6365,12 +6508,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
6365
6508
  /***/ }),
6366
6509
 
6367
6510
  /***/ 8490:
6368
- /***/ ((__unused_webpack_module, exports) => {
6511
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
6369
6512
 
6370
6513
  "use strict";
6371
6514
 
6372
6515
  Object.defineProperty(exports, "__esModule", ({ value: true }));
6373
6516
  exports.collapseableSection = exports.repeatOnFailure = exports.sanitizeForBashVariable = exports.allowFailureInScripts = void 0;
6517
+ const globalScriptFunctions_1 = __nccwpck_require__(2912);
6374
6518
  const allowFailureInScripts = (script) => [
6375
6519
  "set +e", // disable fail job on error
6376
6520
  ...script,
@@ -6389,11 +6533,18 @@ const repeatOnFailure = (command, options) => {
6389
6533
  `;
6390
6534
  };
6391
6535
  exports.repeatOnFailure = repeatOnFailure;
6536
+ const start = (0, globalScriptFunctions_1.registerGlobalScriptFunction)("collapseable_section_start", `local section_title="\${1}"
6537
+ local section_description="\${2:-$section_title}"
6538
+ echo -e "section_start:\`date +%s\`:\${section_title}[collapsed=true]\\r\\e[0K$\{section_description}"
6539
+ `);
6540
+ const end = (0, globalScriptFunctions_1.registerGlobalScriptFunction)("collapseable_section_end", `local section_title="\${1}"
6541
+ echo -e "section_end:\`date +%s\`:\${section_title}\\r\\e[0K"
6542
+ `);
6392
6543
  const collapseableSection = (name, header) => (commands) => {
6393
6544
  return [
6394
- `echo -e "\\e[0Ksection_start:$(date +%s):${name}[collapsed=true]\\r\\e[0K${header}"`,
6545
+ start.invoke(`"${name}"`, `"${header}"`),
6395
6546
  ...commands,
6396
- `echo -e "\\e[0Ksection_end:$(date +%s):${name}\\r\\e[0K"`,
6547
+ end.invoke(`"${name}"`),
6397
6548
  ];
6398
6549
  };
6399
6550
  exports.collapseableSection = collapseableSection;
@@ -6525,6 +6676,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
6525
6676
 
6526
6677
  Object.defineProperty(exports, "__esModule", ({ value: true }));
6527
6678
  exports.createVariableValueContainingReferencesFromString = exports.VariableValueContainingReferences = exports.VariableReference = exports.UnresolvableReference = void 0;
6679
+ const BashExpression_1 = __nccwpck_require__(2376);
6528
6680
  const bashEscape_1 = __nccwpck_require__(2463);
6529
6681
  class UnresolvableReference {
6530
6682
  constructor(reference) {
@@ -6553,11 +6705,16 @@ class VariableValueContainingReferences {
6553
6705
  ? []
6554
6706
  : [part]);
6555
6707
  }
6556
- toString(options = { escape: false }) {
6708
+ toString(options = {
6709
+ quotes: false,
6710
+ }) {
6557
6711
  return this.parts
6558
6712
  .map((part) => {
6559
6713
  if (typeof part === "string") {
6560
- return options.escape ? (0, bashEscape_1.escapeString)(part, options.escape) : part;
6714
+ return (0, bashEscape_1.escapeString)(part, options);
6715
+ }
6716
+ else if (part instanceof BashExpression_1.BashExpression) {
6717
+ return (0, bashEscape_1.escapeBashExpression)(part, options);
6561
6718
  }
6562
6719
  else {
6563
6720
  return part.toString();
@@ -3998,35 +3998,132 @@ exports.joinBashExpressions = joinBashExpressions;
3998
3998
  "use strict";
3999
3999
 
4000
4000
  Object.defineProperty(exports, "__esModule", ({ value: true }));
4001
- exports.escapeSingleQuotes = exports.escapeDoubleQuotes = exports.escapeString = exports.bashEscape = void 0;
4001
+ exports.escapeForDotEnv = exports.escapeSingleQuotes = exports.escapeDoubleQuotes = exports.escapeBashExpression = exports.escapeString = exports.bashEscape = void 0;
4002
+ const globalScriptFunctions_1 = __nccwpck_require__(12912);
4002
4003
  const VariableValueContainingReferences_1 = __nccwpck_require__(84474);
4003
4004
  const BashExpression_1 = __nccwpck_require__(42376);
4004
4005
  /**
4005
4006
  * escapes a string or bash expression for bash
4006
4007
  * it either can escape single or double quotes (double is default)
4007
4008
  */
4008
- const bashEscape = (value, mode = "double") => {
4009
+ const bashEscape = (value, options = {
4010
+ quotes: "double",
4011
+ }) => {
4009
4012
  if (value instanceof BashExpression_1.BashExpression) {
4010
- return value.toString(); // no need to escape bash expressions, as we want them to evaluate
4013
+ // no need to escape
4014
+ return (0, exports.escapeBashExpression)(value, options);
4011
4015
  }
4012
4016
  if (value instanceof VariableValueContainingReferences_1.VariableValueContainingReferences) {
4013
- return value.toString({
4014
- escape: mode,
4015
- });
4017
+ return value.toString(options);
4016
4018
  }
4017
- return (0, exports.escapeString)(value, mode);
4019
+ return (0, exports.escapeString)(value, options);
4018
4020
  };
4019
4021
  exports.bashEscape = bashEscape;
4020
- const escapeString = (value, mode = "double") => {
4021
- return mode === "double"
4022
- ? (0, exports.escapeDoubleQuotes)(value)
4023
- : (0, exports.escapeSingleQuotes)(value);
4022
+ const escapeString = (value, { quotes } = {
4023
+ quotes: "double",
4024
+ }) => {
4025
+ const quoteEscaped = quotes
4026
+ ? quotes === "single"
4027
+ ? (0, exports.escapeSingleQuotes)(value)
4028
+ : (0, exports.escapeDoubleQuotes)(value)
4029
+ : value;
4030
+ return quoteEscaped;
4024
4031
  };
4025
4032
  exports.escapeString = escapeString;
4033
+ const escapeBashExpression = (value, options) => {
4034
+ // no need to escape, we just return the string
4035
+ return value;
4036
+ };
4037
+ exports.escapeBashExpression = escapeBashExpression;
4026
4038
  const escapeDoubleQuotes = (value) => value === null || value === void 0 ? void 0 : value.toString().replace(/"/g, '\\"');
4027
4039
  exports.escapeDoubleQuotes = escapeDoubleQuotes;
4028
4040
  const escapeSingleQuotes = (value) => value === null || value === void 0 ? void 0 : value.toString().replace(/'/g, "\\'");
4029
4041
  exports.escapeSingleQuotes = escapeSingleQuotes;
4042
+ /**
4043
+ *
4044
+ * what an absolute nightmare.
4045
+ * unfortunatly, dotenv has many limitations. You can't escape quotes properly.
4046
+ *
4047
+ * In order to be very forgiving, we need to do some magic here:
4048
+ *
4049
+ * - when the value contains no newlines, we are fine
4050
+ * - if the value contains newlines, we need to wrap it in quotes. And thats where the problem begins:
4051
+ * - you can't escape quotes. this is a shitty limitation of dotenv and node
4052
+ * - you can have inner quotes, but they break in node.js (not in dotenv though), see https://github.com/nodejs/node/issues/54134
4053
+ * - so we need to quote cleverly
4054
+ * - to make things worse, we need to check whether we have a simple stirng or a bash expression, that needs to be evalulated first...
4055
+ */
4056
+ const escapeForDotEnv = (value) => {
4057
+ if (value === undefined || value === null) {
4058
+ return "";
4059
+ }
4060
+ if (typeof value === "string") {
4061
+ // if string contains newlines, we need to wrap it in quotes
4062
+ // we additionaly escape newlines, that give best compatibility
4063
+ if (value.includes("\n")) {
4064
+ const newlinesReplaces = value.replace(/\n/g, "\\n");
4065
+ // default to ", but if this is not possible, we try to use ' or `
4066
+ const quote = value.includes(`"`)
4067
+ ? value.includes(`'`)
4068
+ ? value.includes("`")
4069
+ ? // If all quote types are present, default to no
4070
+ ""
4071
+ : "`"
4072
+ : "'"
4073
+ : '"';
4074
+ // if we found a quote, we can wrap the string in it
4075
+ return `${quote}${newlinesReplaces}${quote}`;
4076
+ }
4077
+ else {
4078
+ // otherwise we can return as is
4079
+ return value;
4080
+ }
4081
+ }
4082
+ else if (value instanceof BashExpression_1.BashExpression) {
4083
+ return escapeBashExpressionForDotEnv(value);
4084
+ }
4085
+ else if (value instanceof VariableValueContainingReferences_1.VariableValueContainingReferences) {
4086
+ // instead of doing it part-wise, we just do it all at once
4087
+ const containsAnyBashExpression = value.parts.some((part) => part instanceof BashExpression_1.BashExpression);
4088
+ if (!containsAnyBashExpression) {
4089
+ return (0, exports.escapeForDotEnv)(value.toString({
4090
+ quotes: "double",
4091
+ }));
4092
+ }
4093
+ else {
4094
+ const result = escapeBashExpressionForDotEnv(new BashExpression_1.BashExpression(value.toString({
4095
+ quotes: "double",
4096
+ })));
4097
+ return result;
4098
+ }
4099
+ }
4100
+ else {
4101
+ return value;
4102
+ }
4103
+ };
4104
+ exports.escapeForDotEnv = escapeForDotEnv;
4105
+ // basically the same thing as above for bash
4106
+ // thx chatgpt for this
4107
+ const escapeForDotEnvScript = (0, globalScriptFunctions_1.registerGlobalScriptFunction)("escapeForDotEnv", `
4108
+ input="\${1:-$(cat)}"
4109
+ input="\${input//$'\\n'/\\\\n}"
4110
+ if [[ "$input" == *\\\\n* ]]; then
4111
+ if [[ "$input" == *\\"* && "$input" == *\\'* && "$input" == *\\\`* ]]; then
4112
+ printf "%s\\n" "$input"
4113
+ elif [[ "$input" == *\\"* && "$input" == *\\'* ]]; then
4114
+ printf "\`%s\`\\n" "$input"
4115
+ elif [[ "$input" == *\\"* ]]; then
4116
+ printf "'%s'\\n" "$input"
4117
+ else
4118
+ printf "\\"%s\\"\\n" "$input"
4119
+ fi
4120
+ else
4121
+ printf "%s\\n" "$input"
4122
+ fi
4123
+ `);
4124
+ const escapeBashExpressionForDotEnv = (value) => {
4125
+ return value.transformWithCommand(escapeForDotEnvScript.name).toString();
4126
+ };
4030
4127
  //# sourceMappingURL=bashEscape.js.map
4031
4128
 
4032
4129
  /***/ }),
@@ -4088,7 +4185,8 @@ const variableContainingReferences = {
4088
4185
  const stringified = value.parts
4089
4186
  .map((part) => part instanceof BashExpression_1.BashExpression
4090
4187
  ? indentNewlinesInBashExpression(part, ctx.indent)
4091
- : part.toString().replace(/\n/g, `\n${ctx.indent}`))
4188
+ : // indent every new line
4189
+ part.toString().replace(/\n/g, `\n${ctx.indent}`))
4092
4190
  .join("");
4093
4191
  return "|-\n" + ctx.indent + stringified;
4094
4192
  },
@@ -4140,7 +4238,11 @@ const getInjectVarsScript = (vars) => {
4140
4238
  // filter out null and undefined values
4141
4239
  return Object.entries(vars)
4142
4240
  .filter(([, value]) => !(0, lodash_1.isNil)(value))
4143
- .map(([key, value]) => `export ${key}="${value ? (0, bashEscape_1.bashEscape)(value) : ""}"`);
4241
+ .map(([key, value]) => `export ${key}="${value
4242
+ ? (0, bashEscape_1.bashEscape)(value, {
4243
+ quotes: "double",
4244
+ })
4245
+ : ""}"`);
4144
4246
  };
4145
4247
  exports.getInjectVarsScript = getInjectVarsScript;
4146
4248
  //# sourceMappingURL=getInjectVarsScript.js.map
@@ -4463,9 +4565,9 @@ exports.writeBuildInfo = writeBuildInfo;
4463
4565
  Object.defineProperty(exports, "__esModule", ({ value: true }));
4464
4566
  exports.componentContextNeedsBuildTimeDotEnv = exports.writeDotEnv = void 0;
4465
4567
  const lodash_1 = __nccwpck_require__(23255);
4466
- const gitlab_1 = __nccwpck_require__(38490);
4467
- const getBuildInfoVariables_1 = __nccwpck_require__(17827);
4468
4568
  const bashEscape_1 = __nccwpck_require__(12463);
4569
+ const getBuildInfoVariables_1 = __nccwpck_require__(17827);
4570
+ const gitlab_1 = __nccwpck_require__(38490);
4469
4571
  /**
4470
4572
  * writes a .env file in the components folder
4471
4573
  * @param context
@@ -4480,10 +4582,9 @@ const writeDotEnv = (context) => {
4480
4582
  // filter out build variables, since they may interfer with caching like turbo
4481
4583
  // build variables are rarely used anyway and we may treat them differently in the future
4482
4584
  .filter(([key]) => !getBuildInfoVariables_1.ALL_BUILD_VARIABLES.includes(key))
4483
- // double quotes seems not to work in some cases
4484
- .map(([key, value]) => `${key}='${(0, bashEscape_1.bashEscape)(value, "single")}'`)
4585
+ .map(([key, value]) => `${key}=${(0, bashEscape_1.escapeForDotEnv)(value)}`)
4485
4586
  .join("\n");
4486
- return (0, gitlab_1.collapseableSection)("write-dotenv-" + context.name, "write dot env")([
4587
+ return (0, gitlab_1.collapseableSection)("write-dotenv-" + context.name, "write dot env for " + context.name)([
4487
4588
  `cat <<EOF > ${context.build.dir}/.env
4488
4589
  ${keyValueString}
4489
4590
  EOF`,
@@ -8365,6 +8466,45 @@ exports.contextIsStoppable = contextIsStoppable;
8365
8466
 
8366
8467
  /***/ }),
8367
8468
 
8469
+ /***/ 12912:
8470
+ /***/ ((__unused_webpack_module, exports) => {
8471
+
8472
+ "use strict";
8473
+
8474
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
8475
+ exports.registerGlobalScriptFunction = exports.globalScriptFunctions = void 0;
8476
+ class GlobalScriptFunction {
8477
+ constructor(name, script) {
8478
+ this.name = name;
8479
+ this.script = script;
8480
+ }
8481
+ toBashFunction() {
8482
+ return `function ${this.name} () {
8483
+ ${this.script.trim()}
8484
+ }`.trim();
8485
+ }
8486
+ invoke(...args) {
8487
+ return `${this.name} ${args.join(" ")}`;
8488
+ }
8489
+ }
8490
+ exports.globalScriptFunctions = new Map();
8491
+ /**
8492
+ * registers a global script function
8493
+ * only use that in top-level scopes as it will attach the function to the global scope
8494
+ */
8495
+ const registerGlobalScriptFunction = (name, script) => {
8496
+ if (exports.globalScriptFunctions.has(name)) {
8497
+ throw new Error(`Global script function ${name} already exists`);
8498
+ }
8499
+ const scriptFunction = new GlobalScriptFunction(name, script);
8500
+ exports.globalScriptFunctions.set(name, scriptFunction);
8501
+ return scriptFunction;
8502
+ };
8503
+ exports.registerGlobalScriptFunction = registerGlobalScriptFunction;
8504
+ //# sourceMappingURL=index.js.map
8505
+
8506
+ /***/ }),
8507
+
8368
8508
  /***/ 10603:
8369
8509
  /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
8370
8510
 
@@ -8993,7 +9133,8 @@ function getGitlabNeedsForWorkspaceJob(context, { needsStages, needs }, allJobs)
8993
9133
  Object.defineProperty(exports, "__esModule", ({ value: true }));
8994
9134
  exports.createGitlabPipelineWithDefaults = void 0;
8995
9135
  const runner_1 = __nccwpck_require__(4058);
8996
- const createGitlabPipelineWithDefaults = ({ image, variables, ...config }) => {
9136
+ const globalScriptFunctions_1 = __nccwpck_require__(12912);
9137
+ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, ...config }) => {
8997
9138
  return {
8998
9139
  image: image !== null && image !== void 0 ? image : (0, runner_1.getRunnerImage)("jobs-default"), // default image
8999
9140
  variables: {
@@ -9004,6 +9145,10 @@ const createGitlabPipelineWithDefaults = ({ image, variables, ...config }) => {
9004
9145
  GIT_DEPTH: "1", // no need the full depth
9005
9146
  ...(variables !== null && variables !== void 0 ? variables : {}),
9006
9147
  },
9148
+ before_script: [
9149
+ ...[...globalScriptFunctions_1.globalScriptFunctions.values()].map((script) => script.toBashFunction()),
9150
+ ...(before_script !== null && before_script !== void 0 ? before_script : []),
9151
+ ],
9007
9152
  ...config,
9008
9153
  };
9009
9154
  };
@@ -9536,12 +9681,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
9536
9681
  /***/ }),
9537
9682
 
9538
9683
  /***/ 38490:
9539
- /***/ ((__unused_webpack_module, exports) => {
9684
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
9540
9685
 
9541
9686
  "use strict";
9542
9687
 
9543
9688
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9544
9689
  exports.collapseableSection = exports.repeatOnFailure = exports.sanitizeForBashVariable = exports.allowFailureInScripts = void 0;
9690
+ const globalScriptFunctions_1 = __nccwpck_require__(12912);
9545
9691
  const allowFailureInScripts = (script) => [
9546
9692
  "set +e", // disable fail job on error
9547
9693
  ...script,
@@ -9560,11 +9706,18 @@ const repeatOnFailure = (command, options) => {
9560
9706
  `;
9561
9707
  };
9562
9708
  exports.repeatOnFailure = repeatOnFailure;
9709
+ const start = (0, globalScriptFunctions_1.registerGlobalScriptFunction)("collapseable_section_start", `local section_title="\${1}"
9710
+ local section_description="\${2:-$section_title}"
9711
+ echo -e "section_start:\`date +%s\`:\${section_title}[collapsed=true]\\r\\e[0K$\{section_description}"
9712
+ `);
9713
+ const end = (0, globalScriptFunctions_1.registerGlobalScriptFunction)("collapseable_section_end", `local section_title="\${1}"
9714
+ echo -e "section_end:\`date +%s\`:\${section_title}\\r\\e[0K"
9715
+ `);
9563
9716
  const collapseableSection = (name, header) => (commands) => {
9564
9717
  return [
9565
- `echo -e "\\e[0Ksection_start:$(date +%s):${name}[collapsed=true]\\r\\e[0K${header}"`,
9718
+ start.invoke(`"${name}"`, `"${header}"`),
9566
9719
  ...commands,
9567
- `echo -e "\\e[0Ksection_end:$(date +%s):${name}\\r\\e[0K"`,
9720
+ end.invoke(`"${name}"`),
9568
9721
  ];
9569
9722
  };
9570
9723
  exports.collapseableSection = collapseableSection;
@@ -9696,6 +9849,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
9696
9849
 
9697
9850
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9698
9851
  exports.createVariableValueContainingReferencesFromString = exports.VariableValueContainingReferences = exports.VariableReference = exports.UnresolvableReference = void 0;
9852
+ const BashExpression_1 = __nccwpck_require__(42376);
9699
9853
  const bashEscape_1 = __nccwpck_require__(12463);
9700
9854
  class UnresolvableReference {
9701
9855
  constructor(reference) {
@@ -9724,11 +9878,16 @@ class VariableValueContainingReferences {
9724
9878
  ? []
9725
9879
  : [part]);
9726
9880
  }
9727
- toString(options = { escape: false }) {
9881
+ toString(options = {
9882
+ quotes: false,
9883
+ }) {
9728
9884
  return this.parts
9729
9885
  .map((part) => {
9730
9886
  if (typeof part === "string") {
9731
- return options.escape ? (0, bashEscape_1.escapeString)(part, options.escape) : part;
9887
+ return (0, bashEscape_1.escapeString)(part, options);
9888
+ }
9889
+ else if (part instanceof BashExpression_1.BashExpression) {
9890
+ return (0, bashEscape_1.escapeBashExpression)(part, options);
9732
9891
  }
9733
9892
  else {
9734
9893
  return part.toString();
@@ -1 +1 @@
1
- {"version":3,"file":"printVariables.js","sourceRoot":"","sources":["../../../../../src/apps/catenv/printVariables.ts"],"names":[],"mappings":";;;AACA,oEAAmE;AAEnE,mCAIiB;AAEjB,MAAM,sBAAsB,GAAG,KAAK,EAAE,MAAc,EAAE,MAAe,EAAE,EAAE;;IACvE,MAAM,EAAE,GAAG,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAA,2CAAmC,EACzE,MAAM,EACN,MAAM,CACP,CAAC;IAEF,IAAI,gBAAgB,EAAE,CAAC;QACrB,wCAAwC;QACxC,IAAI,MAAA,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,MAAM,mCAAI,IAAI,EAAE,CAAC;YACvD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,MAAM,IAAA,qCAAkB,EAAC,IAAI,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC/D,CAAC;SAAM,CAAC;QACN,6DAA6D;QAC7D,0EAA0E;QAC1E,mCAAmC;QACnC,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAChD,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE;;YAC3B,wCAAwC;YACxC,IAAI,MAAA,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,MAAM,mCAAI,IAAI,EAAE,CAAC;gBACpD,OAAO,MAAM,GAAG,CAAC;YACnB,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,IAAA,qCAAkB,EAAC,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;YACtE,OAAO,UAAU,CAAC,mBAAmB,CAAC,CAAC;YACvC,OAAO;gBACL,GAAG,CAAC,MAAM,GAAG,CAAC;gBACd,GAAG,UAAU;gBACb,qCAAqC;gBACrC,GAAG,MAAM,CAAC,WAAW,CACnB,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;oBAC/C,GAAG,IAAA,0BAAkB,EAAC,aAAa,CAAC,WAAW,EAAE,CAAC,IAAI,GAAG,EAAE;oBAC3D,KAAK;iBACN,CAAC,CACH;aACF,CAAC;QACJ,CAAC,EACD,OAAO,CAAC,OAAO,CAAC,EAA4B,CAAC,CAC9C,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEK,MAAM,cAAc,GAAG,KAAK,EAAE,MAAc,EAAE,MAAe,EAAE,EAAE;IACtE,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/D,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC;AAJW,QAAA,cAAc,kBAIzB;AAEF,MAAM,wBAAwB,GAAG,CAAC,SAAoB,EAAE,EAAE,CACxD,IAAA,0BAAkB,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"printVariables.js","sourceRoot":"","sources":["../../../../../src/apps/catenv/printVariables.ts"],"names":[],"mappings":";;;AACA,oEAAmE;AAEnE,mCAIiB;AAEjB,MAAM,sBAAsB,GAAG,KAAK,EAAE,MAAc,EAAE,MAAe,EAAE,EAAE;;IACvE,MAAM,EAAE,GAAG,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAA,2CAAmC,EACzE,MAAM,EACN,MAAM,CACP,CAAC;IAEF,IAAI,gBAAgB,EAAE,CAAC;QACrB,wCAAwC;QACxC,IAAI,MAAA,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,MAAM,mCAAI,IAAI,EAAE,CAAC;YACvD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,MAAM,IAAA,qCAAkB,EAAC,IAAI,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC/D,CAAC;SAAM,CAAC;QACN,6DAA6D;QAC7D,0EAA0E;QAC1E,mCAAmC;QACnC,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAChD,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE;;YAC3B,wCAAwC;YACxC,IAAI,MAAA,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,MAAM,mCAAI,IAAI,EAAE,CAAC;gBACpD,OAAO,MAAM,GAAG,CAAC;YACnB,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,IAAA,qCAAkB,EAAC,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;YACtE,OAAO,UAAU,CAAC,mBAAmB,CAAC,CAAC;YACvC,OAAO;gBACL,GAAG,CAAC,MAAM,GAAG,CAAC;gBACd,GAAG,UAAU;gBACb,qCAAqC;gBACrC,GAAG,MAAM,CAAC,WAAW,CACnB,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;oBAC/C,GAAG,IAAA,0BAAkB,EAAC,aAAa,CAAC,WAAW,EAAE,CAAC,IAAI,GAAG,EAAE;oBAC3D,KAAK;iBACN,CAAC,CACH;aACF,CAAC;QACJ,CAAC,EACD,OAAO,CAAC,OAAO,CAAC,EAA4B,CAAC,CAC9C,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEK,MAAM,cAAc,GAAG,KAAK,EAAE,MAAc,EAAE,MAAe,EAAE,EAAE;IACtE,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE/D,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC;AAJW,QAAA,cAAc,kBAIzB;AAEF,MAAM,wBAAwB,GAAG,CAAC,SAAiC,EAAE,EAAE,CACrE,IAAA,0BAAkB,EAAC,SAAS,EAAE,SAAS,CAAC,CAAC"}
@@ -1,6 +1,4 @@
1
- import type { VariableValue } from "../../../../pipeline/src/index.js";
2
1
  export type Choice = {
3
2
  env?: string;
4
3
  componentName?: string;
5
4
  };
6
- export type Variables = Record<string, VariableValue>;