@constructor-io/constructorio-connect-cli 1.10.0 → 1.12.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 (47) hide show
  1. package/README.md +11 -2
  2. package/boilerplate-repo/.env.example +2 -1
  3. package/dist/commands/deploy.d.ts +3 -3
  4. package/dist/commands/deploy.d.ts.map +1 -1
  5. package/dist/commands/deploy.js +5 -4
  6. package/dist/commands/execute.d.ts +3 -3
  7. package/dist/commands/execute.d.ts.map +1 -1
  8. package/dist/commands/execute.js +13 -10
  9. package/dist/commands/generate-fixture.d.ts +3 -3
  10. package/dist/commands/generate-fixture.d.ts.map +1 -1
  11. package/dist/commands/generate-fixture.js +9 -8
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +1 -6
  14. package/dist/commands/refresh-connections-command.d.ts +6 -0
  15. package/dist/commands/refresh-connections-command.d.ts.map +1 -0
  16. package/dist/commands/refresh-connections-command.js +14 -0
  17. package/dist/commands/trigger-catalog-sync.d.ts +3 -3
  18. package/dist/commands/trigger-catalog-sync.d.ts.map +1 -1
  19. package/dist/commands/trigger-catalog-sync.js +4 -4
  20. package/dist/customer/config.d.ts +15 -2
  21. package/dist/customer/config.d.ts.map +1 -1
  22. package/dist/customer/config.js +194 -2
  23. package/dist/customer/get-connect-token.d.ts.map +1 -1
  24. package/dist/customer/get-connect-token.js +52 -18
  25. package/dist/functions/execute-template.js +5 -5
  26. package/dist/helpers/build-config-file.d.ts +11 -0
  27. package/dist/helpers/build-config-file.d.ts.map +1 -1
  28. package/dist/helpers/build-config-file.js +41 -8
  29. package/dist/helpers/print-warnings.d.ts +10 -1
  30. package/dist/helpers/print-warnings.d.ts.map +1 -1
  31. package/dist/helpers/print-warnings.js +10 -2
  32. package/dist/helpers/refresh-connections-list.d.ts +2 -0
  33. package/dist/helpers/refresh-connections-list.d.ts.map +1 -0
  34. package/dist/helpers/refresh-connections-list.js +103 -0
  35. package/dist/helpers/should-update-connections-list.d.ts +9 -0
  36. package/dist/helpers/should-update-connections-list.d.ts.map +1 -0
  37. package/dist/helpers/should-update-connections-list.js +42 -0
  38. package/dist/http/http-client.d.ts +5 -1
  39. package/dist/http/http-client.d.ts.map +1 -1
  40. package/dist/http/http-client.js +11 -6
  41. package/dist/http/obtain-token-request.d.ts +7 -0
  42. package/dist/http/obtain-token-request.d.ts.map +1 -0
  43. package/dist/http/obtain-token-request.js +25 -0
  44. package/dist/version.d.ts +1 -1
  45. package/dist/version.js +1 -1
  46. package/oclif.manifest.json +20 -1
  47. package/package.json +3 -2
package/README.md CHANGED
@@ -14,7 +14,7 @@ This package is a CLI tool that helps you **build, test and deploy your connecto
14
14
  Before you begin, note that this package is intended for use with partner connections. If you don't have a connector
15
15
  running yet, please take a look at [our documentation](https://docs.constructor.com/docs/integrating-with-constructor-platform-connectors) to see how you can get started.
16
16
 
17
- Finally, make sure you have your **connect auth token** available. If you don't have this yet, please get in touch with our team and we'll set this up.
17
+ Finally, make sure you have your **Index Key** and **API token** available. If you don't have this yet, please get in touch with our team and we'll set this up.
18
18
 
19
19
  ## 2. Install
20
20
 
@@ -28,7 +28,7 @@ Where `my-repo` is the name of the folder and repository you want to create.
28
28
 
29
29
  With the new repository initialized, you can start developing your catalog integration. Please refer to our [documentation](https://docs.constructor.com/docs/integrating-with-constructor-platform-connectors) for more information on how to build your templates.
30
30
 
31
- ## 3. Commands
31
+ ## 3. Commands
32
32
 
33
33
  <!-- Generated code below. Do not update! -->
34
34
 
@@ -38,6 +38,7 @@ With the new repository initialized, you can start developing your catalog integ
38
38
  * [`constructorio-connect-cli generate-fixture`](#constructorio-connect-cli-generate-fixture)
39
39
  * [`constructorio-connect-cli help [COMMAND]`](#constructorio-connect-cli-help-command)
40
40
  * [`constructorio-connect-cli init NAME`](#constructorio-connect-cli-init-name)
41
+ * [`constructorio-connect-cli refresh-connections-command`](#constructorio-connect-cli-refresh-connections-command)
41
42
  * [`constructorio-connect-cli trigger-catalog-sync`](#constructorio-connect-cli-trigger-catalog-sync)
42
43
 
43
44
  ## `constructorio-connect-cli deploy ENV`
@@ -167,6 +168,14 @@ EXAMPLES
167
168
  ```
168
169
 
169
170
 
171
+ ## `constructorio-connect-cli refresh-connections-command`
172
+
173
+ ```
174
+ USAGE
175
+ $ constructorio-connect-cli refresh-connections-command
176
+ ```
177
+
178
+
170
179
  ## `constructorio-connect-cli trigger-catalog-sync`
171
180
 
172
181
  Triggers a catalog sync for selected connection.
@@ -1 +1,2 @@
1
- CONNECT_AUTH_TOKEN=
1
+ CONNECT_AUTH_TOKEN=
2
+ AUTO_REFRESH_CONNECTIONS=true
@@ -1,10 +1,10 @@
1
- import { Command } from "@oclif/core";
2
- export default class Deploy extends Command {
1
+ import { RefreshConnectionsCommand } from "./refresh-connections-command";
2
+ export default class Deploy extends RefreshConnectionsCommand {
3
3
  static args: {
4
4
  env: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
5
5
  };
6
6
  static description: string;
7
7
  static examples: string[];
8
- run(): Promise<any>;
8
+ runCommand(): Promise<any>;
9
9
  }
10
10
  //# sourceMappingURL=deploy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAM,MAAM,aAAa,CAAC;AAchD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,OAAO;IACzC,MAAM,CAAC,IAAI;;MAMT;IAEF,MAAM,CAAC,WAAW,SAGqF;IAEvG,MAAM,CAAC,QAAQ,WAIb;IAEI,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;CAgD1B"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,yBAAyB;IAC3D,MAAM,CAAC,IAAI;;MAMT;IAEF,MAAM,CAAC,WAAW,SAGqF;IAEvG,MAAM,CAAC,QAAQ,WAIb;IAEI,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC;CAgDjC"}
@@ -6,13 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const core_1 = require("@oclif/core");
7
7
  const errors_1 = require("@oclif/core/lib/errors");
8
8
  const kleur_1 = __importDefault(require("kleur"));
9
- const deploy_request_1 = require("../http/deploy-request");
10
9
  const config_1 = require("../customer/config");
10
+ const get_connect_token_1 = require("../customer/get-connect-token");
11
11
  const template_source_code_1 = require("../customer/template-source-code");
12
12
  const ux_action_1 = require("../helpers/ux-action");
13
+ const deploy_request_1 = require("../http/deploy-request");
13
14
  const render_tip_1 = require("../rendering/render-tip");
14
- const get_connect_token_1 = require("../customer/get-connect-token");
15
- class Deploy extends core_1.Command {
15
+ const refresh_connections_command_1 = require("./refresh-connections-command");
16
+ class Deploy extends refresh_connections_command_1.RefreshConnectionsCommand {
16
17
  static args = {
17
18
  env: core_1.Args.string({
18
19
  options: ["development", "qa", "production", "demo"],
@@ -29,7 +30,7 @@ class Deploy extends core_1.Command {
29
30
  "$ <%= config.bin %> deploy qa",
30
31
  "$ <%= config.bin %> deploy production",
31
32
  ];
32
- async run() {
33
+ async runCommand() {
33
34
  const { args } = await this.parse(Deploy);
34
35
  const config = await (0, ux_action_1.uxAction)("📡 Reading your config", async () => {
35
36
  return await (0, config_1.getRepositoryConfigFile)();
@@ -1,4 +1,4 @@
1
- import { Command } from "@oclif/core";
1
+ import { RefreshConnectionsCommand } from "./refresh-connections-command";
2
2
  export declare const executePromptMessages: {
3
3
  readonly template: "Select a template to execute";
4
4
  readonly fixture: "Select a catalog fixture to run the template against";
@@ -15,7 +15,7 @@ interface ExecuteInputFlags {
15
15
  "fixture-path"?: string;
16
16
  "external-data-path"?: string;
17
17
  }
18
- export declare class Execute extends Command {
18
+ export declare class Execute extends RefreshConnectionsCommand {
19
19
  static flags: {
20
20
  "template-path": import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
21
21
  "fixture-path": import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -25,7 +25,7 @@ export declare class Execute extends Command {
25
25
  static description: string;
26
26
  static examples: string[];
27
27
  input: ExecuteInputFlags;
28
- run(): Promise<void>;
28
+ runCommand(): Promise<void>;
29
29
  /**
30
30
  * Returns the template type, which is always equal to the folder name of the template path.
31
31
  */
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,OAAO,EAAE,MAAM,aAAa,CAAC;AA8B7C,eAAO,MAAM,qBAAqB;;;;;CAKxB,CAAC;AAEX;;;GAGG;AACH,UAAU,iBAAiB;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAYD,qBAAa,OAAQ,SAAQ,OAAO;IAClC,MAAM,CAAC,KAAK;;;;;MAgBV;IAEF,MAAM,CAAC,WAAW,SACkK;IAEpL,MAAM,CAAC,QAAQ,WAOb;IAEF,KAAK,EAAE,iBAAiB,CAAM;IAExB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC1B;;OAEG;IACH,OAAO,CAAC,eAAe;YAKT,UAAU;YAsBV,oBAAoB;YA+CpB,qBAAqB;YA0BrB,wBAAwB;CAevC"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,eAAO,MAAM,qBAAqB;;;;;CAKxB,CAAC;AAEX;;;GAGG;AACH,UAAU,iBAAiB;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAYD,qBAAa,OAAQ,SAAQ,yBAAyB;IACpD,MAAM,CAAC,KAAK;;;;;MAgBV;IAEF,MAAM,CAAC,WAAW,SACkK;IAEpL,MAAM,CAAC,QAAQ,WAOb;IAEF,KAAK,EAAE,iBAAiB,CAAM;IAExB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkCjC;;OAEG;IACH,OAAO,CAAC,eAAe;YAKT,UAAU;YAsBV,oBAAoB;YA+CpB,qBAAqB;YA0BrB,wBAAwB;CAevC"}
@@ -7,28 +7,29 @@ exports.Execute = exports.executePromptMessages = void 0;
7
7
  const os_1 = __importDefault(require("os"));
8
8
  const core_1 = require("@oclif/core");
9
9
  const errors_1 = require("@oclif/core/lib/errors");
10
+ const config_1 = require("../customer/config");
11
+ const path_1 = require("../customer/path");
12
+ const template_source_code_1 = require("../customer/template-source-code");
10
13
  const file_loaders_1 = require("../helpers/file-loaders");
11
- const send_template_execute_request_1 = require("../http/send-template-execute-request");
14
+ const print_warnings_1 = require("../helpers/print-warnings");
15
+ const ux_action_1 = require("../helpers/ux-action");
12
16
  const get_connections_request_1 = require("../http/get-connections-request");
17
+ const send_template_execute_request_1 = require("../http/send-template-execute-request");
13
18
  const filter_connections_by_template_1 = require("../prompt-data/filter-connections-by-template");
14
19
  const get_candidate_fixtures_1 = require("../prompt-data/get-candidate-fixtures");
15
- const get_template_files_1 = require("../prompt-data/get-template-files");
16
20
  const get_external_data_files_1 = require("../prompt-data/get-external-data-files");
21
+ const get_template_files_1 = require("../prompt-data/get-template-files");
17
22
  const render_prompt_1 = require("../prompt-data/render-prompt");
18
23
  const render_repeat_input_1 = require("../rendering/render-repeat-input");
19
24
  const render_template_result_1 = require("../rendering/render-template-result");
20
- const path_1 = require("../customer/path");
21
- const config_1 = require("../customer/config");
22
- const template_source_code_1 = require("../customer/template-source-code");
23
- const ux_action_1 = require("../helpers/ux-action");
24
- const print_warnings_1 = require("../helpers/print-warnings");
25
+ const refresh_connections_command_1 = require("./refresh-connections-command");
25
26
  exports.executePromptMessages = {
26
27
  template: "Select a template to execute",
27
28
  fixture: "Select a catalog fixture to run the template against",
28
29
  externalData: "Select external data to run the template against",
29
30
  connection: "Select a connection to execute templates against",
30
31
  };
31
- class Execute extends core_1.Command {
32
+ class Execute extends refresh_connections_command_1.RefreshConnectionsCommand {
32
33
  static flags = {
33
34
  "template-path": core_1.Flags.string({
34
35
  description: "The path to the template to execute. Must be in the 'src/templates' directory.",
@@ -53,7 +54,7 @@ class Execute extends core_1.Command {
53
54
  "$ <%= config.bin %> execute --template-path=mapping/mapping.jsonata",
54
55
  ];
55
56
  input = {};
56
- async run() {
57
+ async runCommand() {
57
58
  try {
58
59
  const templateInput = await this.getTemplateExecInput();
59
60
  const config = await (0, ux_action_1.uxAction)("📡 Reading your config", async () => {
@@ -71,7 +72,9 @@ class Execute extends core_1.Command {
71
72
  });
72
73
  (0, render_template_result_1.renderTemplateResult)(result);
73
74
  if (result.warnings.length > 0) {
74
- (0, print_warnings_1.printExecutionWarnings)(result.warnings);
75
+ (0, print_warnings_1.printExecutionWarnings)({
76
+ warnings: result.warnings,
77
+ });
75
78
  }
76
79
  if (!result?.success) {
77
80
  this.exit(1);
@@ -1,9 +1,9 @@
1
- import { Command } from "@oclif/core";
2
- export default class GenerateFixture extends Command {
1
+ import { RefreshConnectionsCommand } from "./refresh-connections-command";
2
+ export default class GenerateFixture extends RefreshConnectionsCommand {
3
3
  static args: {};
4
4
  static description: string;
5
5
  static examples: string[];
6
- run(): Promise<any>;
6
+ runCommand(): Promise<any>;
7
7
  getFixturePath(type: string, filename: string): string;
8
8
  }
9
9
  //# sourceMappingURL=generate-fixture.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-fixture.d.ts","sourceRoot":"","sources":["../../src/commands/generate-fixture.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAM,MAAM,aAAa,CAAC;AAa1C,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;IAClD,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAIhB;IAEF,MAAM,CAAC,QAAQ,WAA4C;IAErD,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAkDzB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAU9C"}
1
+ {"version":3,"file":"generate-fixture.d.ts","sourceRoot":"","sources":["../../src/commands/generate-fixture.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,yBAAyB;IACpE,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAIhB;IAEF,MAAM,CAAC,QAAQ,WAA4C;IAErD,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC;IAkDhC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAU9C"}
@@ -4,18 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const path_1 = __importDefault(require("path"));
7
+ const prompts_1 = require("@inquirer/prompts");
7
8
  const core_1 = require("@oclif/core");
8
9
  const fs_extra_1 = require("fs-extra");
9
- const prompts_1 = require("@inquirer/prompts");
10
+ const path_2 = require("../customer/path");
11
+ const file_exists_1 = require("../helpers/file-exists");
10
12
  const ux_action_1 = require("../helpers/ux-action");
11
- const render_tip_1 = require("../rendering/render-tip");
12
- const render_prompt_1 = require("../prompt-data/render-prompt");
13
- const types_1 = require("../types");
14
13
  const get_fixture_1 = require("../http/get-fixture");
15
- const file_exists_1 = require("../helpers/file-exists");
16
- const path_2 = require("../customer/path");
14
+ const render_prompt_1 = require("../prompt-data/render-prompt");
17
15
  const select_connections_1 = require("../prompt-data/select-connections");
18
- class GenerateFixture extends core_1.Command {
16
+ const render_tip_1 = require("../rendering/render-tip");
17
+ const types_1 = require("../types");
18
+ const refresh_connections_command_1 = require("./refresh-connections-command");
19
+ class GenerateFixture extends refresh_connections_command_1.RefreshConnectionsCommand {
19
20
  static args = {};
20
21
  static description = `
21
22
  This command will fetch one fixture from the server and save it into a specified file. This fixture file will be an example of how the data would be passed to the connector when executing the templates.\n
@@ -23,7 +24,7 @@ You are expected to customize this file to match the data you expect to cover in
23
24
  Finally, if the file already exists you'll be prompted to overwrite it.
24
25
  `;
25
26
  static examples = ["$ <%= config.bin %> generate-fixture"];
26
- async run() {
27
+ async runCommand() {
27
28
  const connectionId = await (0, select_connections_1.selectConnections)("Choose the connection to generate the fixture for");
28
29
  const type = await (0, render_prompt_1.renderPrompt)({
29
30
  promptMessage: "Choose the type of fixture you want to generate",
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAMA,OAAO,EAAQ,OAAO,EAAM,MAAM,aAAa,CAAC;AAyBhD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,OAAO;IACvC,MAAM,CAAC,WAAW,SAA4D;IAE9E,MAAM,CAAC,QAAQ,WAGb;IAEF,MAAM,CAAC,IAAI;;MAKT;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YA+BnB,UAAU;IAmBxB,OAAO,CAAC,oBAAoB;YAUd,UAAU;YAsBV,uBAAuB;WA+BvB,mBAAmB,CAC/B,MAAM,EAAE,MAAM,EACd,4BAA4B,EAAE,OAAO,GACpC,IAAI;IAcP,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAWjC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAuBlC,OAAO,CAAC,0BAA0B;CA4BnC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAMA,OAAO,EAAQ,OAAO,EAAM,MAAM,aAAa,CAAC;AAyBhD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,OAAO;IACvC,MAAM,CAAC,WAAW,SAA4D;IAE9E,MAAM,CAAC,QAAQ,WAGb;IAEF,MAAM,CAAC,IAAI;;MAKT;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YA8BnB,UAAU;IAmBxB,OAAO,CAAC,oBAAoB;YAUd,UAAU;YAsBV,uBAAuB;WA6BvB,mBAAmB,CAC/B,MAAM,EAAE,MAAM,EACd,4BAA4B,EAAE,OAAO,GACpC,IAAI;IAcP,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAWjC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAuBlC,OAAO,CAAC,0BAA0B;CA4BnC"}
@@ -72,11 +72,7 @@ class Init extends core_1.Command {
72
72
  async run() {
73
73
  const { args } = await this.parse(Init);
74
74
  const repoPath = path.join(process.cwd(), args.name);
75
- core_1.ux.info([
76
- `👋 Welcome to the ${kleur_1.default.bold("Constructor.io Connect CLI")}!\n`,
77
- "Working with this CLI requires a Constructor Connect Auth Token. This is not the same as your Constructor API Token.",
78
- `If you don't have one yet, please reach out over at partners@constructor.io.`,
79
- ].join("\n"));
75
+ core_1.ux.info([`👋 Welcome to the ${kleur_1.default.bold("Constructor.io Connect CLI")}!\n`].join("\n"));
80
76
  const connectAuthToken = await (0, get_connect_token_1.getConnectToken)(false);
81
77
  const newDirExists = fs_extra_1.default.existsSync(repoPath);
82
78
  if (!newDirExists) {
@@ -127,7 +123,6 @@ class Init extends core_1.Command {
127
123
  `);
128
124
  }
129
125
  async generateRepositoryFiles(args) {
130
- core_1.ux.log("\n");
131
126
  const connections = await (0, get_connections_request_1.getConnections)({ showLogs: true });
132
127
  const shouldCreateMappingTemplates = connections.some((connection) => connection.partner === "omni");
133
128
  const connectionsDict = (0, build_config_file_1.buildConnectionsDictFromList)(connections);
@@ -0,0 +1,6 @@
1
+ import { Command } from "@oclif/core";
2
+ export declare abstract class RefreshConnectionsCommand extends Command {
3
+ abstract runCommand(): Promise<any>;
4
+ run(): Promise<any>;
5
+ }
6
+ //# sourceMappingURL=refresh-connections-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh-connections-command.d.ts","sourceRoot":"","sources":["../../src/commands/refresh-connections-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAItC,8BAAsB,yBAA0B,SAAQ,OAAO;IAC7D,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC;IAE7B,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;CAM1B"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RefreshConnectionsCommand = void 0;
4
+ const core_1 = require("@oclif/core");
5
+ const refresh_connections_list_1 = require("../helpers/refresh-connections-list");
6
+ class RefreshConnectionsCommand extends core_1.Command {
7
+ async run() {
8
+ if (!process.env.IS_CI && process.env.AUTO_REFRESH_CONNECTIONS) {
9
+ await (0, refresh_connections_list_1.refreshConnectionsList)();
10
+ }
11
+ return await this.runCommand();
12
+ }
13
+ }
14
+ exports.RefreshConnectionsCommand = RefreshConnectionsCommand;
@@ -1,8 +1,8 @@
1
- import { Command } from "@oclif/core";
2
- export default class TriggerCatalogSync extends Command {
1
+ import { RefreshConnectionsCommand } from "./refresh-connections-command";
2
+ export default class TriggerCatalogSync extends RefreshConnectionsCommand {
3
3
  static args: {};
4
4
  static description: string;
5
5
  static examples: string[];
6
- run(): Promise<any>;
6
+ runCommand(): Promise<any>;
7
7
  }
8
8
  //# sourceMappingURL=trigger-catalog-sync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trigger-catalog-sync.d.ts","sourceRoot":"","sources":["../../src/commands/trigger-catalog-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAMtC,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;IACrD,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAGqF;IAEvG,MAAM,CAAC,QAAQ,WAA2B;IAEpC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;CAS1B"}
1
+ {"version":3,"file":"trigger-catalog-sync.d.ts","sourceRoot":"","sources":["../../src/commands/trigger-catalog-sync.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,yBAAyB;IACvE,MAAM,CAAC,IAAI,KAAM;IAEjB,MAAM,CAAC,WAAW,SAGqF;IAEvG,MAAM,CAAC,QAAQ,WAA2B;IAEpC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC;CASjC"}
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const core_1 = require("@oclif/core");
4
3
  const trigger_catalog_sync_1 = require("../http/trigger-catalog-sync");
5
- const render_tip_1 = require("../rendering/render-tip");
6
4
  const select_connections_1 = require("../prompt-data/select-connections");
7
- class TriggerCatalogSync extends core_1.Command {
5
+ const render_tip_1 = require("../rendering/render-tip");
6
+ const refresh_connections_command_1 = require("./refresh-connections-command");
7
+ class TriggerCatalogSync extends refresh_connections_command_1.RefreshConnectionsCommand {
8
8
  static args = {};
9
9
  static description = `
10
10
  Triggers a catalog sync for selected connection.
11
11
 
12
12
  The script will use the \`CONNECT_AUTH_TOKEN\` environment variable to authenticate with Constructor.`;
13
13
  static examples = ["$ <%= config.bin %>"];
14
- async run() {
14
+ async runCommand() {
15
15
  const connectionId = await (0, select_connections_1.selectConnections)("Choose the connection to a trigger catalog sync");
16
16
  await (0, trigger_catalog_sync_1.triggerCatalogSync)({ connectionId });
17
17
  (0, render_tip_1.renderTip)(["🚀 Catalog sync triggered successfully!"]);
@@ -1,6 +1,19 @@
1
- import { type Config } from "../types";
1
+ import { type Config, type ConnectionConfigDict } from "../types";
2
2
  /**
3
- * @returns The parsed connectrc.js file.
3
+ * @returns The exported config from the connectrc.js file .
4
+ * @throws CLIError if the connectrc.js file is not found or contains a syntax error.
5
+ * @description This function attempts to load the connectrc.js file from the root directory of the repository.
6
+ * If the file is not found, it throws a CLIError with a message indicating the expected path.
4
7
  */
5
8
  export declare function getRepositoryConfigFile(): Promise<Config>;
9
+ /**
10
+ * Reads the content of the connectrc.js file and returns the connections object and the content of the file
11
+ * @returns The connections object and the content of the connectrc.js file in {@link RawConfigContent}
12
+ */
13
+ export declare function getRepositoryConnectionsAndConfig(): Promise<RawConfigContent>;
14
+ interface RawConfigContent {
15
+ fileContent: string;
16
+ existingConnections: ConnectionConfigDict;
17
+ }
18
+ export {};
6
19
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/customer/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAIvC;;GAEG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,CAsC/D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/customer/config.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAIlE;;;;;GAKG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,CAsC/D;AAED;;;GAGG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAyCnF;AA8HD,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,oBAAoB,CAAC;CAC3C"}
@@ -1,11 +1,50 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.getRepositoryConfigFile = getRepositoryConfigFile;
4
- const errors_1 = require("@oclif/core/lib/errors");
37
+ exports.getRepositoryConnectionsAndConfig = getRepositoryConnectionsAndConfig;
38
+ const fs = __importStar(require("fs/promises"));
5
39
  const core_1 = require("@oclif/core");
40
+ const errors_1 = require("@oclif/core/lib/errors");
41
+ const print_warnings_1 = require("../helpers/print-warnings");
6
42
  const path_1 = require("./path");
7
43
  /**
8
- * @returns The parsed connectrc.js file.
44
+ * @returns The exported config from the connectrc.js file .
45
+ * @throws CLIError if the connectrc.js file is not found or contains a syntax error.
46
+ * @description This function attempts to load the connectrc.js file from the root directory of the repository.
47
+ * If the file is not found, it throws a CLIError with a message indicating the expected path.
9
48
  */
10
49
  async function getRepositoryConfigFile() {
11
50
  const configPath = (0, path_1.getCustomerPath)("connectrc.js");
@@ -37,3 +76,156 @@ pointing to the correct connectrc.js directory.`,
37
76
  });
38
77
  }
39
78
  }
79
+ /**
80
+ * Reads the content of the connectrc.js file and returns the connections object and the content of the file
81
+ * @returns The connections object and the content of the connectrc.js file in {@link RawConfigContent}
82
+ */
83
+ async function getRepositoryConnectionsAndConfig() {
84
+ const configPath = (0, path_1.getCustomerPath)("connectrc.js");
85
+ const fileContent = await readRawConfigFile(configPath);
86
+ // Get the connections object from the content of the connectrc.js file
87
+ const configMatch = fileContent.match(/const\s+connections\s*=\s*({[\s\S]*?});/);
88
+ if (isEmptyFileContent(fileContent, configPath) ||
89
+ !hasConfigMatch(configMatch) ||
90
+ !configMatch // just for configMatch[1] below since hasConfigMatch already checks for !configMatch
91
+ ) {
92
+ return { fileContent: "", existingConnections: {} };
93
+ }
94
+ // Remove trailing commas from the connections object
95
+ const connectionsStr = configMatch[1].replace(/,(\s*[}\]])/g, "$1");
96
+ try {
97
+ return {
98
+ fileContent,
99
+ existingConnections: JSON.parse(connectionsStr),
100
+ };
101
+ }
102
+ catch (error) {
103
+ if (hasUnexpectedToken(error)) {
104
+ return handleUnexpectedTokenError(error, connectionsStr, fileContent);
105
+ }
106
+ else {
107
+ (0, print_warnings_1.printExecutionWarnings)({
108
+ warnings: [
109
+ {
110
+ type: "Config",
111
+ critical: true,
112
+ message: `Failed to parse the connections object in connectrc.js. Are you running a custom setup?`,
113
+ },
114
+ ],
115
+ showDocsLink: false,
116
+ });
117
+ return { fileContent, existingConnections: {} };
118
+ }
119
+ }
120
+ }
121
+ /**
122
+ * Reads the content of the connectrc.js file
123
+ * @param configPath The path to the connectrc.js file
124
+ * @returns The content of the connectrc.js file
125
+ */
126
+ async function readRawConfigFile(configPath) {
127
+ try {
128
+ return await fs.readFile(configPath, "utf-8");
129
+ }
130
+ catch (error) {
131
+ // If this function is called and "" is returned, it means that the file does not exist since
132
+ // connectrc.js is not supposed to be a blank file anyway
133
+ return "";
134
+ }
135
+ }
136
+ /**
137
+ * Checks if the content of the connectrc.js file is empty
138
+ * @param fileContent The content of the connectrc.js file
139
+ * @param configPath The path to the connectrc.js file
140
+ * @returns true if the content of the connectrc.js file is empty
141
+ */
142
+ function isEmptyFileContent(fileContent, configPath) {
143
+ if (!fileContent) {
144
+ (0, print_warnings_1.printExecutionWarnings)({
145
+ warnings: [
146
+ {
147
+ type: "Config",
148
+ critical: true,
149
+ message: `Could not find a connectrc.js file in the root directory!\nExpected to be at: ${configPath}`,
150
+ },
151
+ ],
152
+ showDocsLink: false,
153
+ });
154
+ return true;
155
+ }
156
+ return false;
157
+ }
158
+ /**
159
+ * Checks if the connections object is found in the connectrc.js file
160
+ * @param configMatch The result of matching the connections object in the connectrc.js file
161
+ * @returns true if the connections object is found in the connectrc.js file
162
+ */
163
+ function hasConfigMatch(configMatch) {
164
+ if (!configMatch) {
165
+ (0, print_warnings_1.printExecutionWarnings)({
166
+ warnings: [
167
+ {
168
+ type: "Config",
169
+ critical: true,
170
+ message: "Could not find the `connections` variable in connectrc.js to keep your connections up to date. Are you running a custom setup?",
171
+ },
172
+ ],
173
+ showDocsLink: false,
174
+ });
175
+ return false;
176
+ }
177
+ return true;
178
+ }
179
+ /**
180
+ * Checks if the error is an unexpected token error
181
+ * @param error The error that is thrown when getting connections from connectrc.js
182
+ * @returns true if the error is an unexpected token error
183
+ */
184
+ function hasUnexpectedToken(error) {
185
+ return (error instanceof SyntaxError &&
186
+ error.message.includes("Unexpected token") &&
187
+ error.message.includes("in JSON at position"));
188
+ }
189
+ /**
190
+ * Checks if the connections object has properties without quotation marks, try to parse it with the properties in quotation marks
191
+ * and if it's the same, it means that there's something wrong with the connection name (perhaps a quotation mark in the name)
192
+ * @param _error The error that is thrown when getting connections from connectrc.js
193
+ * @param connectionsStr The connections object in connectrc.js
194
+ * @param fileContent The content of connectrc.js
195
+ * @returns The connections object and the content of connectrc.js
196
+ */
197
+ function handleUnexpectedTokenError(_error, connectionsStr, fileContent) {
198
+ const QuotedConnectionStr = addQuotationMarksToProperties(connectionsStr);
199
+ if (connectionsStr !== QuotedConnectionStr) {
200
+ return {
201
+ fileContent,
202
+ existingConnections: JSON.parse(QuotedConnectionStr),
203
+ };
204
+ }
205
+ else {
206
+ (0, print_warnings_1.printExecutionWarnings)({
207
+ warnings: [
208
+ {
209
+ type: "Config",
210
+ critical: true,
211
+ message: `Unable to parse the connections object. Please make sure that the config
212
+ file is defined as it was previously generated in the repo, as running custom setups to
213
+ map your connections isn't supported when automatically updating those.`,
214
+ },
215
+ ],
216
+ showDocsLink: false,
217
+ });
218
+ return { fileContent, existingConnections: {} };
219
+ }
220
+ }
221
+ /**
222
+ * Adds quotation marks to all properties in the {@link PartialConnection} make it JSON parsable
223
+ * @param connectionsStr The connections object in connectrc.js
224
+ * @returns The connections object with the specified properties in quotation marks
225
+ */
226
+ function addQuotationMarksToProperties(connectionsStr) {
227
+ return connectionsStr.replace(/({\s*)([^{}]*)(\s*})/g, (_match, p1, p2, p3) => {
228
+ const updatedProperties = p2.replace(/(\w+):/g, '"$1":');
229
+ return `${p1}${updatedProperties}${p3}`;
230
+ });
231
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"get-connect-token.d.ts","sourceRoot":"","sources":["../../src/customer/get-connect-token.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,eAIvB,OAAO,KACf,OAAO,CAAC,MAAM,CAAC,CA2BnB;AAED,eAAO,MAAM,eAAe,aA9Bf,OAAO,KACf,OAAO,CAAC,MAAM,CA6BkC,CAAC"}
1
+ {"version":3,"file":"get-connect-token.d.ts","sourceRoot":"","sources":["../../src/customer/get-connect-token.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,eAIvB,OAAO,KACf,OAAO,CAAC,MAAM,CAAC,CAyCnB;AAED,eAAO,MAAM,eAAe,aA5Cf,OAAO,KACf,OAAO,CAAC,MAAM,CA2CkC,CAAC"}
@@ -32,12 +32,19 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
39
  exports.getConnectToken = void 0;
37
40
  exports.getConnectTokenStore = getConnectTokenStore;
38
41
  const fs = __importStar(require("fs-extra"));
39
42
  const prompts_1 = require("@inquirer/prompts");
40
43
  const core_1 = require("@oclif/core");
44
+ const kleur_1 = __importDefault(require("kleur"));
45
+ const terminal_link_1 = __importDefault(require("terminal-link"));
46
+ const obtain_token_request_1 = require("../http/obtain-token-request");
47
+ const render_tip_1 = require("../rendering/render-tip");
41
48
  /**
42
49
  * Gets the Connect Auth token that should be used for the API requests to the Connect API.
43
50
  * First attempts to read from the environment variable CONNECT_AUTH_TOKEN. If it is not present
@@ -53,27 +60,54 @@ const core_1 = require("@oclif/core");
53
60
  function getConnectTokenStore() {
54
61
  let connectToken;
55
62
  return async function getConnectToken(canSave = true) {
56
- if (!connectToken) {
57
- if (!process.env.CONNECT_AUTH_TOKEN) {
58
- core_1.ux.log();
59
- connectToken = await core_1.ux.prompt("Enter your Connect Auth token 🔐", {
60
- type: "mask",
61
- });
62
- if (canSave) {
63
- const saveToken = await (0, prompts_1.confirm)({
64
- message: "💾 Do you want to save this token in your .env for future use?",
65
- });
66
- if (saveToken) {
67
- fs.appendFileSync(".env", `CONNECT_AUTH_TOKEN=${connectToken}\n`);
68
- }
69
- core_1.ux.log();
70
- }
71
- }
72
- else {
73
- connectToken = process.env.CONNECT_AUTH_TOKEN;
63
+ if (connectToken) {
64
+ return connectToken;
65
+ }
66
+ if (process.env.CONNECT_AUTH_TOKEN) {
67
+ connectToken = process.env.CONNECT_AUTH_TOKEN;
68
+ return connectToken;
69
+ }
70
+ renderAuthHelperText();
71
+ core_1.ux.log();
72
+ const apiKey = await core_1.ux.prompt("Enter your Index key 🔑", {
73
+ type: "normal",
74
+ });
75
+ const apiToken = await core_1.ux.prompt("Enter your API token 🔐", {
76
+ type: "mask",
77
+ });
78
+ connectToken = await (0, obtain_token_request_1.obtainToken)({
79
+ api_key: apiKey,
80
+ api_token: apiToken,
81
+ });
82
+ if (canSave) {
83
+ const saveToken = await (0, prompts_1.confirm)({
84
+ message: "💾 Do you want to save this token in your .env for future use?",
85
+ });
86
+ if (saveToken) {
87
+ fs.appendFileSync(".env", `CONNECT_AUTH_TOKEN=${connectToken}\n`);
74
88
  }
89
+ core_1.ux.log();
75
90
  }
76
91
  return connectToken;
77
92
  };
78
93
  }
79
94
  exports.getConnectToken = getConnectTokenStore();
95
+ function renderAuthHelperText() {
96
+ core_1.ux.info([
97
+ "Working with this CLI requires you to have a Constructor Index Key and Constructor API Token.",
98
+ `If you have any questions, please reach out over at partners@constructor.io.`,
99
+ ].join("\n"));
100
+ core_1.ux.log("");
101
+ (0, render_tip_1.renderTip)([
102
+ `The ${kleur_1.default.bold("Index Key")} should follow this format: key_xxxxxxxxxxxxxxxx`,
103
+ ]);
104
+ (0, render_tip_1.renderTip)([
105
+ `The ${kleur_1.default.bold("API Token")} should follow this format: tok_xxxxxxxxxxxxxxxx`,
106
+ ]);
107
+ (0, render_tip_1.renderTip)([
108
+ `You can obtain an Index key and API Token from the customer dashboard under the ${(0, terminal_link_1.default)(kleur_1.default.bold("Integration > API Integration"), "https://app.constructor.io/dashboard/integration/api_tokens")} tab.`,
109
+ ], { emoji: "🔗" });
110
+ (0, render_tip_1.renderTip)([
111
+ `For more information about authentication, refer to ${(0, terminal_link_1.default)(kleur_1.default.bold("the documentation"), "https://docs.constructor.com/reference/main-authentication")}.`,
112
+ ], { emoji: "📚" });
113
+ }
@@ -5,14 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TYPE_OPTIONS = void 0;
7
7
  exports.executeTemplate = executeTemplate;
8
- const path_1 = __importDefault(require("path"));
9
8
  const os_1 = __importDefault(require("os"));
10
- const send_template_execute_request_1 = require("../http/send-template-execute-request");
9
+ const path_1 = __importDefault(require("path"));
10
+ const config_1 = require("../customer/config");
11
11
  const template_source_code_1 = require("../customer/template-source-code");
12
12
  const file_loaders_1 = require("../helpers/file-loaders");
13
- const config_1 = require("../customer/config");
14
- const get_connections_request_1 = require("../http/get-connections-request");
15
13
  const print_warnings_1 = require("../helpers/print-warnings");
14
+ const get_connections_request_1 = require("../http/get-connections-request");
15
+ const send_template_execute_request_1 = require("../http/send-template-execute-request");
16
16
  exports.TYPE_OPTIONS = [
17
17
  "item",
18
18
  "variation",
@@ -49,7 +49,7 @@ async function executeTemplate(options) {
49
49
  throw new Error(`Error executing template: ${result.error.message}`);
50
50
  }
51
51
  if (result.warnings.length > 0) {
52
- (0, print_warnings_1.printExecutionWarnings)(result.warnings);
52
+ (0, print_warnings_1.printExecutionWarnings)({ warnings: result.warnings });
53
53
  }
54
54
  return result.data;
55
55
  }
@@ -1,6 +1,17 @@
1
1
  import { type ConnectionResponseDto } from "../http/get-connections-request";
2
2
  import { type Config, type ConnectionConfigDict } from "../types";
3
+ /**
4
+ * Builds the config object from the connections list.
5
+ * @param connections
6
+ * @param shouldCreateMappingTemplates
7
+ * @returns the config object
8
+ */
3
9
  export declare function buildConfigFromConnections(connections: ConnectionResponseDto[], shouldCreateMappingTemplates: boolean): Config;
10
+ /**
11
+ * Builds a dictionary of connections from array of connections sorted by environment and name.
12
+ * @param connections Array of connections
13
+ * @returns Dictionary of connections
14
+ */
4
15
  export declare function buildConnectionsDictFromList(connections: ConnectionResponseDto[]): ConnectionConfigDict;
5
16
  export declare function buildConfigString(config: Config, connections: ConnectionConfigDict): string;
6
17
  //# sourceMappingURL=build-config-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-config-file.d.ts","sourceRoot":"","sources":["../../src/helpers/build-config-file.ts"],"names":[],"mappings":"AASA,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,EACpC,4BAA4B,EAAE,OAAO,GACpC,MAAM,CAWR;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,qBAAqB,EAAE,wBAYrC;AAmDD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,oBAAoB,GAChC,MAAM,CAmBR"}
1
+ {"version":3,"file":"build-config-file.d.ts","sourceRoot":"","sources":["../../src/helpers/build-config-file.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAQlE;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,qBAAqB,EAAE,EACpC,4BAA4B,EAAE,OAAO,GACpC,MAAM,CAWR;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,qBAAqB,EAAE,GACnC,oBAAoB,CAiCtB;AAmDD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,oBAAoB,GAChC,MAAM,CAmBR"}
@@ -14,6 +14,17 @@ exports.buildConfigString = buildConfigString;
14
14
  * 4. Map each object in the environments array to expand out
15
15
  */
16
16
  const path_1 = __importDefault(require("path"));
17
+ const environmentOrder = {
18
+ development: 1,
19
+ qa: 2,
20
+ production: 3,
21
+ };
22
+ /**
23
+ * Builds the config object from the connections list.
24
+ * @param connections
25
+ * @param shouldCreateMappingTemplates
26
+ * @returns the config object
27
+ */
17
28
  function buildConfigFromConnections(connections, shouldCreateMappingTemplates) {
18
29
  const environments = getUniqueConnectionEnvs(connections);
19
30
  return {
@@ -21,15 +32,37 @@ function buildConfigFromConnections(connections, shouldCreateMappingTemplates) {
21
32
  environments: buildTemplateEnvironments(environments, connections, shouldCreateMappingTemplates),
22
33
  };
23
34
  }
35
+ /**
36
+ * Builds a dictionary of connections from array of connections sorted by environment and name.
37
+ * @param connections Array of connections
38
+ * @returns Dictionary of connections
39
+ */
24
40
  function buildConnectionsDictFromList(connections) {
25
- return connections.reduce((dict, conn) => {
26
- if (conn.name) {
27
- dict[conn.name] = {
28
- id: conn.id,
29
- slug: conn.slug,
30
- environment: conn.environment,
31
- };
32
- }
41
+ const sortedConnections = connections
42
+ .filter((conn) => conn.name)
43
+ .sort((a, b) => {
44
+ // MAX_SAFE_INTEGER used just in case there are other environments not accounted for
45
+ const envOrderA = environmentOrder[a.environment] ?? Number.MAX_SAFE_INTEGER;
46
+ const envOrderB = environmentOrder[b.environment] ?? Number.MAX_SAFE_INTEGER;
47
+ return (
48
+ /**
49
+ * Sorts connections first by environment order, then by name.
50
+ *
51
+ * Example result:
52
+ *
53
+ * Dev A integration
54
+ * Dev B integration
55
+ * QA integration
56
+ * Prod integration
57
+ **/
58
+ envOrderA - envOrderB || a.name.localeCompare(b.name));
59
+ });
60
+ return sortedConnections.reduce((dict, conn) => {
61
+ dict[conn.name] = {
62
+ id: conn.id,
63
+ slug: conn.slug,
64
+ environment: conn.environment,
65
+ };
33
66
  return dict;
34
67
  }, {});
35
68
  }
@@ -1,3 +1,12 @@
1
1
  import { type TemplateValidatorWarning } from "../types";
2
- export declare function printExecutionWarnings(warnings: TemplateValidatorWarning[]): void;
2
+ export interface PrintExecutionWarningsArgs {
3
+ warnings: TemplateValidatorWarning[];
4
+ showDocsLink?: boolean;
5
+ }
6
+ /**
7
+ * Prints the warnings from the template execution, with a link to the documentation by default unless
8
+ * showDocsLink is set to false.
9
+ * @param {@link PrintExecutionWarningsArgs} args: The warnings to print and whether to show the documentation link (default true)
10
+ */
11
+ export declare function printExecutionWarnings({ warnings, showDocsLink, }: PrintExecutionWarningsArgs): void;
3
12
  //# sourceMappingURL=print-warnings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"print-warnings.d.ts","sourceRoot":"","sources":["../../src/helpers/print-warnings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEzD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,wBAAwB,EAAE,QA8B1E"}
1
+ {"version":3,"file":"print-warnings.d.ts","sourceRoot":"","sources":["../../src/helpers/print-warnings.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEzD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,wBAAwB,EAAE,CAAC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,YAAmB,GACpB,EAAE,0BAA0B,QA+B5B"}
@@ -6,7 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.printExecutionWarnings = printExecutionWarnings;
7
7
  const core_1 = require("@oclif/core");
8
8
  const kleur_1 = __importDefault(require("kleur"));
9
- function printExecutionWarnings(warnings) {
9
+ const terminal_link_1 = __importDefault(require("terminal-link"));
10
+ /**
11
+ * Prints the warnings from the template execution, with a link to the documentation by default unless
12
+ * showDocsLink is set to false.
13
+ * @param {@link PrintExecutionWarningsArgs} args: The warnings to print and whether to show the documentation link (default true)
14
+ */
15
+ function printExecutionWarnings({ warnings, showDocsLink = true, }) {
10
16
  const originalLength = warnings.length;
11
17
  if (warnings.length > 10) {
12
18
  warnings = warnings.slice(0, 10);
@@ -21,7 +27,9 @@ function printExecutionWarnings(warnings) {
21
27
  core_1.ux.log(`... and ${originalLength - 10} more`);
22
28
  }
23
29
  core_1.ux.log();
24
- core_1.ux.log(kleur_1.default.bold(`See Documentation ➡️ :`), kleur_1.default.underline(`https://docs.constructor.com/docs/integrating-with-constructor-connect-cli-template-types-transformation-templates`));
30
+ if (showDocsLink) {
31
+ core_1.ux.log(kleur_1.default.bold(`${(0, terminal_link_1.default)(kleur_1.default.bold("See documentation!"), `https://docs.constructor.com/docs/integrating-with-constructor-connect-cli-template-types-transformation-templates`)}`));
32
+ }
25
33
  }
26
34
  function printSingleWarning(warning) {
27
35
  if (warning.critical) {
@@ -0,0 +1,2 @@
1
+ export declare function refreshConnectionsList(): Promise<void>;
2
+ //# sourceMappingURL=refresh-connections-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh-connections-list.d.ts","sourceRoot":"","sources":["../../src/helpers/refresh-connections-list.ts"],"names":[],"mappings":"AAcA,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAY5D"}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.refreshConnectionsList = refreshConnectionsList;
37
+ const fs = __importStar(require("fs/promises"));
38
+ const cli_ux_1 = require("@oclif/core/lib/cli-ux");
39
+ const config_1 = require("../customer/config");
40
+ const path_1 = require("../customer/path");
41
+ const get_connections_request_1 = require("../http/get-connections-request");
42
+ const render_prompt_1 = require("../prompt-data/render-prompt");
43
+ const build_config_file_1 = require("./build-config-file");
44
+ const should_update_connections_list_1 = require("./should-update-connections-list");
45
+ const ux_action_1 = require("./ux-action");
46
+ async function refreshConnectionsList() {
47
+ try {
48
+ const shouldUpdate = await checkConfigFileState();
49
+ if (!shouldUpdate) {
50
+ return;
51
+ }
52
+ await updateConfigFile();
53
+ }
54
+ catch (error) {
55
+ cli_ux_1.ux.log(`Error refreshing connections list: ${error.message}`);
56
+ }
57
+ }
58
+ async function fetchNewConnections() {
59
+ return (0, build_config_file_1.buildConnectionsDictFromList)(await (0, get_connections_request_1.getConnections)({
60
+ showLogs: false,
61
+ }));
62
+ }
63
+ async function promptForUpdate() {
64
+ return await (0, render_prompt_1.renderPrompt)({
65
+ promptMessage: "💡 Your connections in connectrc.js are out of date. Do you want to update it?",
66
+ choices: [
67
+ { name: "Yes", value: true },
68
+ { name: "No", value: false },
69
+ ],
70
+ });
71
+ }
72
+ async function checkConfigFileState() {
73
+ const formattedConnections = await fetchNewConnections();
74
+ const { fileContent, existingConnections } = await (0, config_1.getRepositoryConnectionsAndConfig)();
75
+ if (!fileContent) {
76
+ return false;
77
+ }
78
+ if (!(0, should_update_connections_list_1.shouldUpdateConnectionList)(existingConnections, formattedConnections)) {
79
+ return false;
80
+ }
81
+ const update = await promptForUpdate();
82
+ if (!update) {
83
+ return false;
84
+ }
85
+ return true;
86
+ }
87
+ async function updateConfigFile() {
88
+ const formattedConnections = await fetchNewConnections();
89
+ const rcPath = (0, path_1.getCustomerPath)("connectrc.js");
90
+ const { fileContent } = await (0, config_1.getRepositoryConnectionsAndConfig)();
91
+ if (!fileContent) {
92
+ return;
93
+ }
94
+ await (0, ux_action_1.uxAction)("Updating connectrc.js", async () => {
95
+ const updatedContent = fileContent.replace(
96
+ // Match the connections object in connectrc.js
97
+ /const\s+connections\s*=\s*({[\s\S]*?});/,
98
+ // Replace the connections object with the new formatted connections
99
+ `const connections = ${JSON.stringify(formattedConnections, null, 2)};`);
100
+ await fs.writeFile(rcPath, updatedContent, "utf-8");
101
+ })();
102
+ cli_ux_1.ux.log("🎉 Successfully updated connections in connectrc.js");
103
+ }
@@ -0,0 +1,9 @@
1
+ import { type ConnectionConfigDict } from "../types";
2
+ /**
3
+ * Checks if the connections in the config file are updated
4
+ * @param oldConnections
5
+ * @param newConnections
6
+ * @returns true if the two connections are equal (ie: connections in the config file are updated)
7
+ */
8
+ export declare function shouldUpdateConnectionList(oldConnections: ConnectionConfigDict, newConnections: ConnectionConfigDict): boolean;
9
+ //# sourceMappingURL=should-update-connections-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"should-update-connections-list.d.ts","sourceRoot":"","sources":["../../src/helpers/should-update-connections-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,oBAAoB,EAA0B,MAAM,UAAU,CAAC;AAE7E;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,oBAAoB,EACpC,cAAc,EAAE,oBAAoB,GACnC,OAAO,CAoBT"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shouldUpdateConnectionList = shouldUpdateConnectionList;
4
+ /**
5
+ * Checks if the connections in the config file are updated
6
+ * @param oldConnections
7
+ * @param newConnections
8
+ * @returns true if the two connections are equal (ie: connections in the config file are updated)
9
+ */
10
+ function shouldUpdateConnectionList(oldConnections, newConnections) {
11
+ const oldConnectionNames = Object.keys(oldConnections);
12
+ const newConnectionNames = Object.keys(newConnections);
13
+ if (oldConnectionNames.length !== newConnectionNames.length) {
14
+ return true;
15
+ }
16
+ for (const name of oldConnectionNames) {
17
+ if (!newConnections[name]) {
18
+ return true;
19
+ }
20
+ if (!areConnectionPropertiesEqual(oldConnections, newConnections, name) ||
21
+ !areConnectionPropertiesEqual(newConnections, oldConnections, name)) {
22
+ return true;
23
+ }
24
+ }
25
+ return false;
26
+ }
27
+ /**
28
+ * Checks if the properties of connection A are present in connection B and whether they have the same values
29
+ * @param connectionsA
30
+ * @param connectionsB
31
+ * @param connectionName
32
+ * @returns true if the properties of connection A are present in connection B and have the same values
33
+ */
34
+ function areConnectionPropertiesEqual(connectionsA, connectionsB, connectionName) {
35
+ for (const property in connectionsA[connectionName]) {
36
+ if (connectionsA[connectionName][property] !==
37
+ connectionsB[connectionName][property]) {
38
+ return false;
39
+ }
40
+ }
41
+ return true;
42
+ }
@@ -1,8 +1,11 @@
1
1
  import axios from "axios";
2
+ interface HttpClientPayload {
3
+ requiresAuth: boolean;
4
+ }
2
5
  /**
3
6
  * @returns An axios instance with the correct base URL and auth token.
4
7
  */
5
- export declare function getHttpClient(): Promise<axios.AxiosInstance>;
8
+ export declare function getHttpClient({ requiresAuth }?: HttpClientPayload): Promise<axios.AxiosInstance>;
6
9
  /**
7
10
  * Checks if a request should be retried.
8
11
  */
@@ -11,4 +14,5 @@ export declare function checkRetryCondition(error: any): boolean;
11
14
  * Calculates the time in ms to wait before retrying the request.
12
15
  */
13
16
  export declare function calculateRetryDelay(retryCount: number, error: any): 2000 | 500;
17
+ export {};
14
18
  //# 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;AA6B5C;;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,cAcjE"}
1
+ {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http/http-client.ts"],"names":[],"mappings":"AACA,OAAO,KAA6C,MAAM,OAAO,CAAC;AA6BlE,UAAU,iBAAiB;IACzB,YAAY,EAAE,OAAO,CAAC;CACvB;AAOD;;GAEG;AACH,wBAAsB,aAAa,CACjC,EAAE,YAAY,EAAE,GAAE,iBAEjB,gCA6DF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,WAK7C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,cAcjE"}
@@ -66,15 +66,20 @@ const MAX_RETRIES = 3;
66
66
  /**
67
67
  * @returns An axios instance with the correct base URL and auth token.
68
68
  */
69
- async function getHttpClient() {
70
- const token = await (0, get_connect_token_1.getConnectToken)();
69
+ async function getHttpClient({ requiresAuth } = {
70
+ requiresAuth: true,
71
+ }) {
72
+ const headers = {
73
+ "X-CLI-Version": version_1.default,
74
+ };
75
+ if (requiresAuth) {
76
+ const token = await (0, get_connect_token_1.getConnectToken)();
77
+ headers.Authorization = `Bearer ${token}`;
78
+ }
71
79
  const baseURL = process.env.HOST ?? "https://connect.cnstrc.com";
72
80
  const instance = axios_1.default.create({
73
81
  baseURL,
74
- headers: {
75
- Authorization: `Bearer ${token}`,
76
- "X-CLI-Version": version_1.default,
77
- },
82
+ headers,
78
83
  });
79
84
  (0, axios_retry_1.default)(instance, {
80
85
  retries: MAX_RETRIES,
@@ -0,0 +1,7 @@
1
+ export declare function obtainToken(args: ObtainTokenArgs): Promise<string>;
2
+ interface ObtainTokenArgs {
3
+ api_key: string;
4
+ api_token: string;
5
+ }
6
+ export {};
7
+ //# sourceMappingURL=obtain-token-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obtain-token-request.d.ts","sourceRoot":"","sources":["../../src/http/obtain-token-request.ts"],"names":[],"mappings":"AAOA,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBxE;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.obtainToken = obtainToken;
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 obtainToken(args) {
9
+ const client = await (0, http_client_1.getHttpClient)({ requiresAuth: false });
10
+ try {
11
+ const response = await (0, ux_action_1.uxAction)("📡 Obtaining connect auth token", async () => {
12
+ return await client.post(`/auth/obtain-token`, args);
13
+ })();
14
+ return response.data.connect_auth_token;
15
+ }
16
+ catch (error) {
17
+ if ((0, axios_1.isAxiosError)(error) && error.response) {
18
+ throw new errors_1.CLIError("Something went wrong while obtaining connect auth token: \n" +
19
+ error.response.data.message +
20
+ "\n" +
21
+ "Please reach out over at partners@constructor.io.");
22
+ }
23
+ throw error;
24
+ }
25
+ }
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- declare const _default: "1.10.0";
1
+ declare const _default: "1.12.0";
2
2
  export default _default;
3
3
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = '1.10.0';
3
+ exports.default = '1.12.0';
@@ -147,6 +147,25 @@
147
147
  "init.js"
148
148
  ]
149
149
  },
150
+ "refresh-connections-command": {
151
+ "aliases": [],
152
+ "args": {},
153
+ "flags": {},
154
+ "hasDynamicHelp": false,
155
+ "hiddenAliases": [],
156
+ "id": "refresh-connections-command",
157
+ "pluginAlias": "@constructor-io/constructorio-connect-cli",
158
+ "pluginName": "@constructor-io/constructorio-connect-cli",
159
+ "pluginType": "core",
160
+ "strict": true,
161
+ "enableJsonFlag": false,
162
+ "isESM": false,
163
+ "relativePath": [
164
+ "dist",
165
+ "commands",
166
+ "refresh-connections-command.js"
167
+ ]
168
+ },
150
169
  "trigger-catalog-sync": {
151
170
  "aliases": [],
152
171
  "args": {},
@@ -171,5 +190,5 @@
171
190
  ]
172
191
  }
173
192
  },
174
- "version": "1.10.0"
193
+ "version": "1.12.0"
175
194
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-connect-cli",
3
- "version": "1.10.0",
3
+ "version": "1.12.0",
4
4
  "description": "CLI tool to enable users to interface with the Constructor Connect Ecosystem",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -73,7 +73,8 @@
73
73
  "kleur": "^4.1.5",
74
74
  "nanospinner": "^1.2.2",
75
75
  "remeda": "^2.5.0",
76
- "replace-in-file": "^7.2.0"
76
+ "replace-in-file": "^7.2.0",
77
+ "terminal-link": "^2.1.1"
77
78
  },
78
79
  "devDependencies": {
79
80
  "@oclif/test": "^4.0.5",