@constructor-io/constructorio-connect-cli 1.3.1 → 1.4.0

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 (77) hide show
  1. package/boilerplate-repo/.github/workflows/test.yml +33 -0
  2. package/boilerplate-repo/.vscode/settings.json +3 -0
  3. package/boilerplate-repo/README.md +31 -2
  4. package/boilerplate-repo/babel.config.json +10 -0
  5. package/boilerplate-repo/eslint.config.js +12 -0
  6. package/boilerplate-repo/jest.config.js +27 -0
  7. package/boilerplate-repo/package.json +8 -8
  8. package/boilerplate-repo/src/fixtures/item_group/item_group.json +1 -1
  9. package/boilerplate-repo/src/templates/item_group/item_group.jsonata +1 -2
  10. package/boilerplate-repo/test/global-setup.js +13 -0
  11. package/boilerplate-repo/test/setup-tests-after-env.js +16 -0
  12. package/boilerplate-repo/test/setup-tests.js +8 -0
  13. package/boilerplate-repo/test/templates/grouping/grouping.spec.mjs +26 -0
  14. package/boilerplate-repo/test/templates/item/item.spec.mjs +86 -0
  15. package/boilerplate-repo/test/templates/item_group/item_group.spec.mjs +23 -0
  16. package/boilerplate-repo/test/templates/mapping/mapping.spec.mjs +78 -0
  17. package/boilerplate-repo/test/templates/variation/variation.spec.mjs +37 -0
  18. package/dist/commands/execute.d.ts.map +1 -1
  19. package/dist/commands/execute.js +6 -4
  20. package/dist/commands/generate-fixture.js +1 -1
  21. package/dist/commands/init.js +1 -1
  22. package/dist/customer/config.js +1 -2
  23. package/dist/customer/get-connect-token.d.ts.map +1 -1
  24. package/dist/customer/get-connect-token.js +2 -2
  25. package/dist/customer/path.js +4 -5
  26. package/dist/customer/template-source-code.d.ts +5 -0
  27. package/dist/customer/template-source-code.d.ts.map +1 -1
  28. package/dist/customer/template-source-code.js +7 -3
  29. package/dist/functions/build-fixture.d.ts +13 -0
  30. package/dist/functions/build-fixture.d.ts.map +1 -0
  31. package/dist/functions/build-fixture.js +21 -0
  32. package/dist/functions/execute-template.d.ts +22 -0
  33. package/dist/functions/execute-template.d.ts.map +1 -0
  34. package/dist/functions/execute-template.js +89 -0
  35. package/dist/helpers/build-config-file.d.ts.map +1 -1
  36. package/dist/helpers/build-config-file.js +9 -5
  37. package/dist/helpers/file-exists.js +1 -2
  38. package/dist/helpers/file-loaders.d.ts +0 -2
  39. package/dist/helpers/file-loaders.d.ts.map +1 -1
  40. package/dist/helpers/file-loaders.js +2 -2
  41. package/dist/helpers/find-deep-files.js +1 -2
  42. package/dist/helpers/generate-command-input.js +1 -2
  43. package/dist/helpers/is-git-repo-initialized.js +1 -2
  44. package/dist/helpers/ux-action.d.ts.map +1 -1
  45. package/dist/helpers/ux-action.js +1 -2
  46. package/dist/http/deploy-request.js +1 -2
  47. package/dist/http/get-connections-request.d.ts +4 -1
  48. package/dist/http/get-connections-request.d.ts.map +1 -1
  49. package/dist/http/get-connections-request.js +12 -6
  50. package/dist/http/get-fixture.js +1 -2
  51. package/dist/http/http-client.d.ts +8 -0
  52. package/dist/http/http-client.d.ts.map +1 -1
  53. package/dist/http/http-client.js +55 -2
  54. package/dist/http/send-template-execute-request.d.ts +12 -0
  55. package/dist/http/send-template-execute-request.d.ts.map +1 -0
  56. package/dist/http/send-template-execute-request.js +31 -0
  57. package/dist/index.d.ts +3 -0
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +9 -1
  60. package/dist/prompt-data/filter-connections-by-template.js +1 -2
  61. package/dist/prompt-data/get-candidate-fixtures.js +1 -2
  62. package/dist/prompt-data/get-external-data-files.js +1 -2
  63. package/dist/prompt-data/get-template-files.js +2 -2
  64. package/dist/prompt-data/render-prompt.js +1 -2
  65. package/dist/rendering/render-repeat-input.js +1 -2
  66. package/dist/rendering/render-template-result.js +1 -2
  67. package/dist/rendering/render-tip.js +1 -2
  68. package/dist/types.d.ts +7 -2
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/version.d.ts +1 -1
  71. package/dist/version.js +1 -1
  72. package/oclif.manifest.json +1 -1
  73. package/package.json +4 -2
  74. package/boilerplate-repo/.eslintrc.json +0 -11
  75. package/dist/http/execute-templates-request.d.ts +0 -10
  76. package/dist/http/execute-templates-request.d.ts.map +0 -1
  77. package/dist/http/execute-templates-request.js +0 -28
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getHelpersSourceCode = exports.getTemplatesSourceCode = void 0;
3
+ exports.getTemplatesSourceCode = getTemplatesSourceCode;
4
+ exports.getHelpersSourceCode = getHelpersSourceCode;
4
5
  const promises_1 = require("fs/promises");
5
6
  const errors_1 = require("@oclif/core/lib/errors");
6
7
  const path_1 = require("./path");
@@ -35,8 +36,11 @@ async function getTemplatesSourceCode(templates) {
35
36
  };
36
37
  }));
37
38
  }
38
- exports.getTemplatesSourceCode = getTemplatesSourceCode;
39
+ /**
40
+ * Loads the helpers source code from the file system.
41
+ * @param helpers The path to the helpers file.
42
+ * @returns The source code.
43
+ */
39
44
  async function getHelpersSourceCode(helpers) {
40
45
  return await loadSourceCode(helpers);
41
46
  }
42
- exports.getHelpersSourceCode = getHelpersSourceCode;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This will build a fixture with the given template type and name.
3
+ *
4
+ * You can also pass in any object in the third argument to override the fixture data,
5
+ * similarly to how a factory pattern works. It'll deep merge into the fixture itself.
6
+ *
7
+ * @param type string The type of fixture
8
+ * @param name string The name/path of the fixture
9
+ * @param dataOverride string The data to override in the fixture
10
+ * @returns Record<string, unknown> The fixture data
11
+ */
12
+ export declare const buildFixture: (type: string, name: string, dataOverride?: Record<string, unknown>) => never;
13
+ //# sourceMappingURL=build-fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-fixture.d.ts","sourceRoot":"","sources":["../../src/functions/build-fixture.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,SACjB,MAAM,QACN,MAAM,iBACE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UAKtC,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFixture = void 0;
4
+ const remeda_1 = require("remeda");
5
+ const file_loaders_1 = require("../helpers/file-loaders");
6
+ /**
7
+ * This will build a fixture with the given template type and name.
8
+ *
9
+ * You can also pass in any object in the third argument to override the fixture data,
10
+ * similarly to how a factory pattern works. It'll deep merge into the fixture itself.
11
+ *
12
+ * @param type string The type of fixture
13
+ * @param name string The name/path of the fixture
14
+ * @param dataOverride string The data to override in the fixture
15
+ * @returns Record<string, unknown> The fixture data
16
+ */
17
+ const buildFixture = (type, name, dataOverride = {}) => {
18
+ const data = (0, file_loaders_1.getCatalogFixture)(`${type}/${name}`);
19
+ return (0, remeda_1.mergeDeep)(data, dataOverride);
20
+ };
21
+ exports.buildFixture = buildFixture;
@@ -0,0 +1,22 @@
1
+ export declare const TYPE_OPTIONS: readonly ["item", "variation", "item_group", "mapping", "grouping"];
2
+ export interface ExecuteTemplateArgs {
3
+ type: (typeof TYPE_OPTIONS)[number];
4
+ name: string;
5
+ fixture?: Record<string, unknown>;
6
+ externalData?: Record<string, unknown>;
7
+ connectionId?: string;
8
+ }
9
+ /**
10
+ * This will execute a template with the given type, name, fixture, and externalData.
11
+ * It returns an object with the result of the execution, or throws if there is an error.
12
+ *
13
+ * The template will be executed against the first connection found, or you can override
14
+ * this behavior and select a specific connection by providing a connectionId.
15
+ *
16
+ * If no connection is found, an error will be thrown.
17
+ *
18
+ * @param options @type ExecuteTemplateArgs
19
+ * @returns Promise<Record<string, any>>
20
+ */
21
+ export declare function executeTemplate(options: ExecuteTemplateArgs): Promise<Record<string, any>>;
22
+ //# sourceMappingURL=execute-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-template.d.ts","sourceRoot":"","sources":["../../src/functions/execute-template.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,YAAY,qEAMf,CAAC;AAEX,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,mBAAmB,gCAoBjE"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TYPE_OPTIONS = void 0;
4
+ exports.executeTemplate = executeTemplate;
5
+ const send_template_execute_request_1 = require("../http/send-template-execute-request");
6
+ const template_source_code_1 = require("../customer/template-source-code");
7
+ const file_loaders_1 = require("../helpers/file-loaders");
8
+ const config_1 = require("../customer/config");
9
+ const get_connections_request_1 = require("../http/get-connections-request");
10
+ exports.TYPE_OPTIONS = [
11
+ "item",
12
+ "variation",
13
+ "item_group",
14
+ "mapping",
15
+ "grouping",
16
+ ];
17
+ /**
18
+ * This will execute a template with the given type, name, fixture, and externalData.
19
+ * It returns an object with the result of the execution, or throws if there is an error.
20
+ *
21
+ * The template will be executed against the first connection found, or you can override
22
+ * this behavior and select a specific connection by providing a connectionId.
23
+ *
24
+ * If no connection is found, an error will be thrown.
25
+ *
26
+ * @param options @type ExecuteTemplateArgs
27
+ * @returns Promise<Record<string, any>>
28
+ */
29
+ async function executeTemplate(options) {
30
+ const { type, name, fixture, externalData } = initializeOptions(options);
31
+ const connection = await getConnection(options);
32
+ const config = await (0, config_1.getRepositoryConfigFile)();
33
+ const result = await (0, send_template_execute_request_1.sendTemplateExecuteRequest)({
34
+ template: (0, file_loaders_1.getJSONataTemplate)(`${type}/${name}`).toString(),
35
+ helpers: (await (0, template_source_code_1.getHelpersSourceCode)(config.helpers)) ?? "",
36
+ connectionId: connection.id,
37
+ targetData: fixture,
38
+ showLogs: false,
39
+ externalData,
40
+ });
41
+ if (!result.success) {
42
+ throw new Error(`Error executing template: ${result.error.message}`);
43
+ }
44
+ return result.data;
45
+ }
46
+ function initializeOptions(options) {
47
+ if (!options) {
48
+ throw new Error("No options provided");
49
+ }
50
+ if (!options.type) {
51
+ throw new Error("No type provided");
52
+ }
53
+ if (!exports.TYPE_OPTIONS.includes(options.type)) {
54
+ throw new Error(`Invalid type: ${options.type}. Expected to receive one of: ${exports.TYPE_OPTIONS.join(", ")}`);
55
+ }
56
+ if (!options.name) {
57
+ throw new Error("No name provided");
58
+ }
59
+ if (!options.fixture) {
60
+ options.fixture = {};
61
+ }
62
+ if (!options.externalData) {
63
+ options.externalData = {};
64
+ }
65
+ return options;
66
+ }
67
+ async function getConnection(options) {
68
+ /**
69
+ * Note: we're loading connections from `global.__connections` first to avoid
70
+ * making an unnecessary request to the API during tests.
71
+ *
72
+ * When running the entire test suite on initialized repos, we want to load
73
+ * all connections only once, and then use them across all tests.
74
+ */
75
+ const connections = "__connections" in global
76
+ ? global.__connections
77
+ : await (0, get_connections_request_1.getConnections)({ showLogs: false });
78
+ let connection;
79
+ if (options.connectionId) {
80
+ connection = connections.find((conn) => conn.id === options.connectionId);
81
+ }
82
+ else {
83
+ connection = connections[0];
84
+ }
85
+ if (!connection) {
86
+ throw new Error(`Connection with id ${options.connectionId} not found`);
87
+ }
88
+ return connection;
89
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"build-config-file.d.ts","sourceRoot":"","sources":["../../src/helpers/build-config-file.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAElE,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,qBAAqB,EAAE,GACnC,MAAM,CAQR;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,qBAAqB,EAAE,wBAYrC;AAkCD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,oBAAoB,GAChC,MAAM,CAUR"}
1
+ {"version":3,"file":"build-config-file.d.ts","sourceRoot":"","sources":["../../src/helpers/build-config-file.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAElE,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,qBAAqB,EAAE,GACnC,MAAM,CAQR;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,qBAAqB,EAAE,wBAYrC;AAkCD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,oBAAoB,GAChC,MAAM,CAmBR"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildConfigString = exports.buildConnectionsDictFromList = exports.buildConfigFromConnections = void 0;
3
+ exports.buildConfigFromConnections = buildConfigFromConnections;
4
+ exports.buildConnectionsDictFromList = buildConnectionsDictFromList;
5
+ exports.buildConfigString = buildConfigString;
4
6
  function buildConfigFromConnections(connections) {
5
7
  const environments = getUniqueConnectionEnvs(connections);
6
8
  return {
@@ -9,7 +11,6 @@ function buildConfigFromConnections(connections) {
9
11
  environments: buildTemplateEnvironments(environments, connections),
10
12
  };
11
13
  }
12
- exports.buildConfigFromConnections = buildConfigFromConnections;
13
14
  function buildConnectionsDictFromList(connections) {
14
15
  return connections.reduce((dict, conn) => {
15
16
  if (conn.name) {
@@ -22,7 +23,6 @@ function buildConnectionsDictFromList(connections) {
22
23
  return dict;
23
24
  }, {});
24
25
  }
25
- exports.buildConnectionsDictFromList = buildConnectionsDictFromList;
26
26
  function getUniqueConnectionEnvs(connections) {
27
27
  return connections.reduce((envs, conn) => {
28
28
  if (!envs.includes(conn.environment))
@@ -55,8 +55,12 @@ function buildConfigString(config, connections) {
55
55
  let configString = JSON.stringify(config, null, 2);
56
56
  for (const connectionName in connections) {
57
57
  const conn = connections[connectionName];
58
- configString = configString.replace(`"${conn.id}"`, `connections["${connectionName}"].id`);
58
+ /**
59
+ * We need to escape the name to ensure the JSON won't break, in case
60
+ * there are special characters in the connection name.
61
+ */
62
+ const escapedName = JSON.stringify(connectionName);
63
+ configString = configString.replace(`"${conn.id}"`, `connections[${escapedName}].id`);
59
64
  }
60
65
  return configString;
61
66
  }
62
- exports.buildConfigString = buildConfigString;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fileExists = void 0;
3
+ exports.fileExists = fileExists;
4
4
  const fs_extra_1 = require("fs-extra");
5
5
  const path_1 = require("../customer/path");
6
6
  /**
@@ -17,4 +17,3 @@ function fileExists(filepath, isCustomerPath = false) {
17
17
  return false;
18
18
  }
19
19
  }
20
- exports.fileExists = fileExists;
@@ -1,5 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
1
  import fs from "fs-extra";
4
2
  export declare const getCatalogFixture: (name: string, options?: fs.JsonReadOptions) => any;
5
3
  export declare const getExternalDataFixture: (name: string, options?: fs.JsonReadOptions) => any;
@@ -1 +1 @@
1
- {"version":3,"file":"file-loaders.d.ts","sourceRoot":"","sources":["../../src/helpers/file-loaders.ts"],"names":[],"mappings":";;AAGA,OAAO,EAAE,MAAM,UAAU,CAAC;AAI1B,eAAO,MAAM,iBAAiB,SAqBP,MAAM,sCAjB3B,CAAC;AAEH,eAAO,MAAM,sBAAsB,SAeZ,MAAM,sCAX3B,CAAC;AAEH,eAAO,MAAM,kBAAkB,SASR,MAAM;;yCAN3B,CAAC;AAEH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE,EAAE,EACnD,MAAM,EACN,UAAU,EACV,WAAgB,GACjB,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAc9C;AAED,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB"}
1
+ {"version":3,"file":"file-loaders.d.ts","sourceRoot":"","sources":["../../src/helpers/file-loaders.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,UAAU,CAAC;AAI1B,eAAO,MAAM,iBAAiB,SAqBP,MAAM,sCAjB3B,CAAC;AAEH,eAAO,MAAM,sBAAsB,SAeZ,MAAM,sCAX3B,CAAC;AAEH,eAAO,MAAM,kBAAkB,SASR,MAAM;;yCAN3B,CAAC;AAEH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE,EAAE,EACnD,MAAM,EACN,UAAU,EACV,WAAgB,GACjB,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAc9C;AAED,UAAU,IAAI,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB"}
@@ -3,7 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createFileLoader = exports.getJSONataTemplate = exports.getExternalDataFixture = exports.getCatalogFixture = void 0;
6
+ exports.getJSONataTemplate = exports.getExternalDataFixture = exports.getCatalogFixture = void 0;
7
+ exports.createFileLoader = createFileLoader;
7
8
  const path_1 = __importDefault(require("path"));
8
9
  const errors_1 = require("@oclif/core/lib/errors");
9
10
  const fs_extra_1 = __importDefault(require("fs-extra"));
@@ -38,4 +39,3 @@ function createFileLoader({ prefix, fileLoader, suggestions = [], }) {
38
39
  }
39
40
  };
40
41
  }
41
- exports.createFileLoader = createFileLoader;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.findDeepFiles = void 0;
6
+ exports.findDeepFiles = findDeepFiles;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
9
9
  const path_2 = require("../customer/path");
@@ -24,4 +24,3 @@ function findDeepFiles(dir) {
24
24
  }
25
25
  }, []);
26
26
  }
27
- exports.findDeepFiles = findDeepFiles;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateCommandInput = void 0;
3
+ exports.generateCommandInput = generateCommandInput;
4
4
  /**
5
5
  * Generates a string representing a command that can be directly pasted
6
6
  * into the terminal from the provided inputs describing the command.
@@ -23,7 +23,6 @@ function generateCommandInput({ commandName, args, inputFlags }) {
23
23
  "\n",
24
24
  ].join("");
25
25
  }
26
- exports.generateCommandInput = generateCommandInput;
27
26
  /**
28
27
  * Sometimes, when executing a command via npm it needs to have double dashes (--) in front of the flags.
29
28
  * This function will add the double dashes, if needed, to the command.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isGitRepoInitialized = void 0;
3
+ exports.isGitRepoInitialized = isGitRepoInitialized;
4
4
  const child_process_1 = require("child_process");
5
5
  /**
6
6
  * Returns true if a git repo is initialized in this folder and false otherwise.
@@ -21,4 +21,3 @@ function isGitRepoInitialized() {
21
21
  return false;
22
22
  }
23
23
  }
24
- exports.isGitRepoInitialized = isGitRepoInitialized;
@@ -1 +1 @@
1
- {"version":3,"file":"ux-action.d.ts","sourceRoot":"","sources":["../../src/helpers/ux-action.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,aAEmB,WAAW,CAAC,CAAC,KAAG,WAAW,CAAC,CAAC,CAwBxD"}
1
+ {"version":3,"file":"ux-action.d.ts","sourceRoot":"","sources":["../../src/helpers/ux-action.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,aAEmB,UAAU,CAAC,CAAC,CAAC,KAAG,UAAU,CAAC,CAAC,CAAC,CAwBxD"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uxAction = void 0;
3
+ exports.uxAction = uxAction;
4
4
  const core_1 = require("@oclif/core");
5
5
  function uxAction(title, func) {
6
6
  return function (...args) {
@@ -28,4 +28,3 @@ function uxAction(title, func) {
28
28
  return result;
29
29
  };
30
30
  }
31
- exports.uxAction = uxAction;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.performDeploy = void 0;
3
+ exports.performDeploy = performDeploy;
4
4
  /* eslint-disable @typescript-eslint/no-base-to-string */
5
5
  const axios_1 = require("axios");
6
6
  const errors_1 = require("@oclif/core/lib/errors");
@@ -42,4 +42,3 @@ async function performDeploy({ environment, config, templates, helpers, }) {
42
42
  throw new errors_1.CLIError(`💥 Received the following error from the Constructor API: \n${logData}}\n`);
43
43
  }
44
44
  }
45
- exports.performDeploy = performDeploy;
@@ -1,4 +1,7 @@
1
- export declare function getConnectionsForCompany(): Promise<ConnectionResponseDto[]>;
1
+ export declare function getConnections({ showLogs, }: GetConnectionsOptions): Promise<ConnectionResponseDto[]>;
2
+ export interface GetConnectionsOptions {
3
+ showLogs: boolean;
4
+ }
2
5
  export interface ConnectionResponseDto {
3
6
  id: string;
4
7
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"get-connections-request.d.ts","sourceRoot":"","sources":["../../src/http/get-connections-request.ts"],"names":[],"mappings":"AAOA,wBAAsB,wBAAwB,IAAI,OAAO,CACvD,qBAAqB,EAAE,CACxB,CAqBA;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB"}
1
+ {"version":3,"file":"get-connections-request.d.ts","sourceRoot":"","sources":["../../src/http/get-connections-request.ts"],"names":[],"mappings":"AAOA,wBAAsB,cAAc,CAAC,EACnC,QAAQ,GACT,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CA8B1D;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB"}
@@ -1,16 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getConnectionsForCompany = void 0;
3
+ exports.getConnections = getConnections;
4
4
  const axios_1 = require("axios");
5
5
  const errors_1 = require("@oclif/core/lib/errors");
6
6
  const ux_action_1 = require("../helpers/ux-action");
7
7
  const http_client_1 = require("./http-client");
8
- async function getConnectionsForCompany() {
8
+ async function getConnections({ showLogs, }) {
9
9
  const client = await (0, http_client_1.getHttpClient)();
10
+ const fetchConnections = async () => {
11
+ return await client.get("/connections");
12
+ };
10
13
  try {
11
- const response = await (0, ux_action_1.uxAction)("📡 Fetching your account details", async () => {
12
- return await client.get("/connections");
13
- })();
14
+ let response;
15
+ if (showLogs) {
16
+ response = await (0, ux_action_1.uxAction)("📡 Fetching your account details", fetchConnections)();
17
+ }
18
+ else {
19
+ response = await fetchConnections();
20
+ }
14
21
  return response.data.connections;
15
22
  }
16
23
  catch (error) {
@@ -21,4 +28,3 @@ async function getConnectionsForCompany() {
21
28
  throw error;
22
29
  }
23
30
  }
24
- exports.getConnectionsForCompany = getConnectionsForCompany;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFixture = void 0;
3
+ exports.getFixture = getFixture;
4
4
  const axios_1 = require("axios");
5
5
  const errors_1 = require("@oclif/core/lib/errors");
6
6
  const ux_action_1 = require("../helpers/ux-action");
@@ -26,4 +26,3 @@ async function getFixture(args) {
26
26
  throw error;
27
27
  }
28
28
  }
29
- exports.getFixture = getFixture;
@@ -3,4 +3,12 @@ import axios from "axios";
3
3
  * @returns An axios instance with the correct base URL and auth token.
4
4
  */
5
5
  export declare function getHttpClient(): Promise<axios.AxiosInstance>;
6
+ /**
7
+ * Checks if a request should be retried.
8
+ */
9
+ export declare function checkRetryCondition(error: any): boolean;
10
+ /**
11
+ * Calculates the time in ms to wait before retrying the request.
12
+ */
13
+ export declare function calculateRetryDelay(retryCount: number, error: any): 2000 | 500;
6
14
  //# sourceMappingURL=http-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http/http-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAuB,MAAM,OAAO,CAAC;AAK5C;;GAEG;AACH,wBAAsB,aAAa,iCAkClC"}
1
+ {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http/http-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAuB,MAAM,OAAO,CAAC;AA0B5C;;GAEG;AACH,wBAAsB,aAAa,iCAwDlC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,WAK7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,cAQjE"}
@@ -26,11 +26,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.getHttpClient = void 0;
29
+ exports.getHttpClient = getHttpClient;
30
+ exports.checkRetryCondition = checkRetryCondition;
31
+ exports.calculateRetryDelay = calculateRetryDelay;
30
32
  const errors_1 = require("@oclif/core/lib/errors");
31
33
  const axios_1 = __importStar(require("axios"));
34
+ const axios_retry_1 = __importDefault(require("axios-retry"));
32
35
  const get_connect_token_1 = require("../customer/get-connect-token");
33
36
  const version_1 = __importDefault(require("../version"));
37
+ const RETRY_IGNORED_HTTP_STATUS_CODES = [
38
+ /**
39
+ * HTTP 400: Bad Request
40
+ * This error is thrown whenever data validation fails.
41
+ */
42
+ 400,
43
+ /**
44
+ * HTTP 401: Unauthorized
45
+ * This error is thrown whenever a user has invalid credentials.
46
+ */
47
+ 401,
48
+ /**
49
+ * HTTP 403: Forbidden
50
+ * This error is thrown whenever a user has no permissions to access a resource.
51
+ */
52
+ 403,
53
+ ];
34
54
  /**
35
55
  * @returns An axios instance with the correct base URL and auth token.
36
56
  */
@@ -44,6 +64,24 @@ async function getHttpClient() {
44
64
  "X-CLI-Version": version_1.default,
45
65
  },
46
66
  });
67
+ (0, axios_retry_1.default)(instance, {
68
+ retries: 3,
69
+ /**
70
+ * Avoid retrying requests that failed because of an authentication error.
71
+ */
72
+ retryCondition: checkRetryCondition,
73
+ /**
74
+ * If we get a 429 response, we want to wait some more time before
75
+ * retrying the request to allow the rate limit to reset.
76
+ */
77
+ retryDelay: calculateRetryDelay,
78
+ /**
79
+ * We want to always retry with the same timeout value.
80
+ * Otherwise axios-retry will only retry the request if
81
+ * the sum of all requests durations are less than the timeout value.
82
+ */
83
+ shouldResetTimeout: true,
84
+ });
47
85
  instance.interceptors.response.use((response) => response, async (error) => {
48
86
  if ((0, axios_1.isAxiosError)(error) && error.response) {
49
87
  if (error.response.status === 403) {
@@ -59,4 +97,19 @@ async function getHttpClient() {
59
97
  });
60
98
  return instance;
61
99
  }
62
- exports.getHttpClient = getHttpClient;
100
+ /**
101
+ * Checks if a request should be retried.
102
+ */
103
+ function checkRetryCondition(error) {
104
+ const status = error?.response?.status;
105
+ const isIgnoredError = RETRY_IGNORED_HTTP_STATUS_CODES.includes(status);
106
+ return !isIgnoredError;
107
+ }
108
+ /**
109
+ * Calculates the time in ms to wait before retrying the request.
110
+ */
111
+ function calculateRetryDelay(retryCount, error) {
112
+ const retryAfterMs = error?.response?.status === 429 ? 2000 : 500;
113
+ console.log(`🧐 Retrying request after ${retryAfterMs}ms. Currently on retry number ${retryCount}.`);
114
+ return retryAfterMs;
115
+ }
@@ -0,0 +1,12 @@
1
+ import { type TemplateExecutionSuccessResponse, type TemplateExecutionErrorResponse } from "../types";
2
+ export declare function sendTemplateExecuteRequest({ template, helpers, targetData, externalData, connectionId, showLogs, }: Args): Promise<TemplateExecutionSuccessResponse | TemplateExecutionErrorResponse>;
3
+ interface Args {
4
+ template: string;
5
+ helpers: string;
6
+ targetData: any;
7
+ externalData: any;
8
+ connectionId: string;
9
+ showLogs?: boolean;
10
+ }
11
+ export {};
12
+ //# sourceMappingURL=send-template-execute-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-template-execute-request.d.ts","sourceRoot":"","sources":["../../src/http/send-template-execute-request.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,gCAAgC,EACrC,KAAK,8BAA8B,EACpC,MAAM,UAAU,CAAC;AAIlB,wBAAsB,0BAA0B,CAAC,EAC/C,QAAQ,EACR,OAAO,EACP,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,QAAe,GAChB,EAAE,IAAI,GAAG,OAAO,CACf,gCAAgC,GAAG,8BAA8B,CAClE,CA6BA;AAED,UAAU,IAAI;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,GAAG,CAAC;IAChB,YAAY,EAAE,GAAG,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendTemplateExecuteRequest = sendTemplateExecuteRequest;
4
+ const axios_1 = require("axios");
5
+ const errors_1 = require("@oclif/core/lib/errors");
6
+ const ux_action_1 = require("../helpers/ux-action");
7
+ const http_client_1 = require("./http-client");
8
+ async function sendTemplateExecuteRequest({ template, helpers, targetData, externalData, connectionId, showLogs = true, }) {
9
+ const client = await (0, http_client_1.getHttpClient)();
10
+ const httpRequest = async () => {
11
+ return (await client.patch("templates/standalone/execute", {
12
+ raw_template: template,
13
+ helpers,
14
+ target_data: targetData,
15
+ external_data: externalData,
16
+ connection_id: connectionId,
17
+ })).data;
18
+ };
19
+ try {
20
+ if (showLogs) {
21
+ return await (0, ux_action_1.uxAction)("📟 Executing your template", httpRequest)();
22
+ }
23
+ return await httpRequest();
24
+ }
25
+ catch (error) {
26
+ if ((0, axios_1.isAxiosError)(error) && error.response) {
27
+ throw new errors_1.CLIError(`Something went wrong while executing your template: ${JSON.stringify(error.response.data)}`);
28
+ }
29
+ throw error;
30
+ }
31
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,5 @@
1
1
  export { run } from "@oclif/core";
2
+ export { executeTemplate } from "./functions/execute-template";
3
+ export { buildFixture } from "./functions/build-fixture";
4
+ export { getConnections } from "./http/get-connections-request";
2
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAIzD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.run = void 0;
3
+ exports.getConnections = exports.buildFixture = exports.executeTemplate = exports.run = void 0;
4
4
  var core_1 = require("@oclif/core");
5
5
  Object.defineProperty(exports, "run", { enumerable: true, get: function () { return core_1.run; } });
6
+ var execute_template_1 = require("./functions/execute-template");
7
+ Object.defineProperty(exports, "executeTemplate", { enumerable: true, get: function () { return execute_template_1.executeTemplate; } });
8
+ var build_fixture_1 = require("./functions/build-fixture");
9
+ Object.defineProperty(exports, "buildFixture", { enumerable: true, get: function () { return build_fixture_1.buildFixture; } });
10
+ // Export the function to load connections to optimize tests in the initialized repos,
11
+ // so that we can load connections only once before all tests.
12
+ var get_connections_request_1 = require("./http/get-connections-request");
13
+ Object.defineProperty(exports, "getConnections", { enumerable: true, get: function () { return get_connections_request_1.getConnections; } });
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.filterConnectionsByTemplate = void 0;
6
+ exports.filterConnectionsByTemplate = filterConnectionsByTemplate;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const config_1 = require("../customer/config");
9
9
  async function filterConnectionsByTemplate(templatePath, connections) {
@@ -27,4 +27,3 @@ async function filterConnectionsByTemplate(templatePath, connections) {
27
27
  };
28
28
  });
29
29
  }
30
- exports.filterConnectionsByTemplate = filterConnectionsByTemplate;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getCandidateFixtures = void 0;
6
+ exports.getCandidateFixtures = getCandidateFixtures;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const errors_1 = require("@oclif/core/lib/errors");
9
9
  const find_deep_files_1 = require("../helpers/find-deep-files");
@@ -46,7 +46,6 @@ function getCandidateFixtures(templatePath) {
46
46
  };
47
47
  });
48
48
  }
49
- exports.getCandidateFixtures = getCandidateFixtures;
50
49
  /**
51
50
  * Checks for any nested folder that matches a known template type.
52
51
  */
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getExternalDataFiles = void 0;
6
+ exports.getExternalDataFiles = getExternalDataFiles;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const find_deep_files_1 = require("../helpers/find-deep-files");
9
9
  function getExternalDataFiles() {
@@ -25,4 +25,3 @@ function getExternalDataFiles() {
25
25
  throw error;
26
26
  }
27
27
  }
28
- exports.getExternalDataFiles = getExternalDataFiles;