@unito/integration-cli 0.57.1 → 0.58.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 (115) hide show
  1. package/dist/.eslintrc.d.ts +6 -0
  2. package/dist/.eslintrc.js +9 -2
  3. package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/src/index.ts +1 -3
  4. package/dist/src/commands/activity.d.ts +2 -2
  5. package/dist/src/commands/activity.js +2 -2
  6. package/dist/src/commands/dev.d.ts +8 -4
  7. package/dist/src/commands/dev.js +42 -5
  8. package/dist/src/commands/encrypt.d.ts +1 -1
  9. package/dist/src/commands/encrypt.js +1 -1
  10. package/dist/src/commands/init.d.ts +1 -1
  11. package/dist/src/commands/init.js +3 -3
  12. package/dist/src/commands/invite.d.ts +1 -1
  13. package/dist/src/commands/invite.js +2 -2
  14. package/dist/src/commands/login.d.ts +1 -1
  15. package/dist/src/commands/login.js +1 -1
  16. package/dist/src/commands/oauth2.d.ts +3 -3
  17. package/dist/src/commands/oauth2.js +19 -14
  18. package/dist/src/commands/publish.d.ts +2 -2
  19. package/dist/src/commands/publish.js +12 -12
  20. package/dist/src/commands/test.js +32 -8
  21. package/dist/src/commands/upgrade.js +3 -3
  22. package/dist/src/errors.d.ts +8 -0
  23. package/dist/src/errors.js +35 -18
  24. package/dist/src/resources/configuration.js +0 -2
  25. package/dist/src/resources/credentials.d.ts +3 -0
  26. package/dist/src/resources/credentials.js +26 -0
  27. package/dist/src/resources/integrations.d.ts +1 -0
  28. package/dist/src/resources/integrations.js +37 -2
  29. package/dist/src/resources/oauth2Helper.d.ts +4 -0
  30. package/dist/src/resources/oauth2Helper.js +30 -0
  31. package/dist/src/services/integrationsPlatform.d.ts +1 -0
  32. package/dist/src/services/integrationsPlatform.js +5 -1
  33. package/dist/src/services/oauth2Helper.d.ts +78 -3
  34. package/dist/src/services/oauth2Helper.js +229 -29
  35. package/dist/test/commands/activity.test.js +12 -9
  36. package/dist/test/commands/dev.test.js +59 -10
  37. package/dist/test/commands/encrypt.test.js +6 -7
  38. package/dist/test/commands/init.test.js +7 -9
  39. package/dist/test/commands/invite.test.js +11 -11
  40. package/dist/test/commands/login.test.js +20 -23
  41. package/dist/test/commands/oauth2.test.js +6 -2
  42. package/dist/test/commands/publish.test.js +152 -218
  43. package/dist/test/commands/test.test.js +65 -13
  44. package/dist/test/commands/upgrade.test.js +4 -6
  45. package/dist/test/errors.test.js +36 -36
  46. package/dist/test/helpers/integrations.d.ts +26 -0
  47. package/dist/test/helpers/integrations.js +25 -0
  48. package/dist/test/helpers/styles.d.ts +1 -0
  49. package/dist/test/helpers/styles.js +8 -0
  50. package/dist/test/oauth2Helper/oauth2Helper.test.js +112 -128
  51. package/dist/test/resources/configuration.test.js +24 -24
  52. package/dist/test/resources/decryption.test.js +9 -9
  53. package/dist/test/resources/globalConfiguration.test.js +4 -4
  54. package/dist/test/resources/integrations.test.js +37 -0
  55. package/dist/test/resources/oauth2Helper.test.js +55 -0
  56. package/dist/test/services/integrationsPlatform.test.js +20 -20
  57. package/oclif.manifest.json +64 -9
  58. package/package.json +10 -14
  59. package/dist/integrationGenerator/errors.d.ts +0 -2
  60. package/dist/integrationGenerator/errors.js +0 -6
  61. package/dist/integrationGenerator/index.d.ts +0 -2
  62. package/dist/integrationGenerator/index.js +0 -5
  63. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.dockerignore +0 -3
  64. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.eslintrc.js +0 -74
  65. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.nvmrc +0 -1
  66. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierignore +0 -1
  67. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.prettierrc +0 -7
  68. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/.unito.json +0 -1
  69. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/Dockerfile +0 -38
  70. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/README.md +0 -21
  71. package/dist/integrationGenerator/integrationBoilerplate/integrationBoilerplate/src/index.ts +0 -94
  72. package/dist/integrationGenerator/integrationBoilerplate/package.json +0 -43
  73. package/dist/integrationGenerator/integrationBoilerplate/src/logger.ts +0 -55
  74. package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/additionalLoggingContext.ts +0 -22
  75. package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/correlationId.ts +0 -13
  76. package/dist/integrationGenerator/integrationBoilerplate/src/middlewares/credentials.ts +0 -38
  77. package/dist/integrationGenerator/integrationBoilerplate/src/request.ts +0 -59
  78. package/dist/integrationGenerator/integrationBoilerplate/src/routes/index.ts +0 -11
  79. package/dist/integrationGenerator/integrationBoilerplate/src/routes/me.ts +0 -15
  80. package/dist/integrationGenerator/integrationBoilerplate/src/routes/root.ts +0 -12
  81. package/dist/integrationGenerator/integrationBoilerplate/tsconfig.json +0 -37
  82. package/dist/integrationGenerator/src/index.d.ts +0 -1
  83. package/dist/integrationGenerator/src/index.js +0 -5
  84. package/dist/integrationGenerator/src/resources/index.d.ts +0 -1
  85. package/dist/integrationGenerator/src/resources/index.js +0 -5
  86. package/dist/integrationGenerator/src/resources/integration.d.ts +0 -9
  87. package/dist/integrationGenerator/src/resources/integration.js +0 -60
  88. package/dist/integrationGenerator/test/resources/integration.test.js +0 -51
  89. package/dist/src/oauth2Helper/oauth2Helper.d.ts +0 -63
  90. package/dist/src/oauth2Helper/oauth2Helper.js +0 -235
  91. package/dist/src/oauth2Helper/types.d.ts +0 -22
  92. package/dist/src/oauth2Helper/types.js +0 -2
  93. package/dist/test/mocha.hooks.d.ts +0 -2
  94. package/dist/test/mocha.hooks.js +0 -37
  95. package/dist/test/services/oauth2Helper.test.js +0 -85
  96. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.dockerignore +0 -0
  97. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.eslintrc.js +0 -0
  98. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.nvmrc +0 -0
  99. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.prettierignore +0 -0
  100. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.prettierrc +0 -0
  101. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/.unito.json +0 -0
  102. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/Dockerfile +0 -0
  103. /package/dist/{integrationGenerator/integrationBoilerplate → boilerplate}/README.md +0 -0
  104. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/package.json +0 -0
  105. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/logger.ts +0 -0
  106. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/additionalLoggingContext.ts +0 -0
  107. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/correlationId.ts +0 -0
  108. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/middlewares/credentials.ts +0 -0
  109. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/request.ts +0 -0
  110. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/index.ts +0 -0
  111. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/me.ts +0 -0
  112. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/src/routes/root.ts +0 -0
  113. /package/dist/{integrationGenerator/integrationBoilerplate/integrationBoilerplate → boilerplate}/tsconfig.json +0 -0
  114. /package/dist/{integrationGenerator/test/resources/integration.test.d.ts → test/resources/integrations.test.d.ts} +0 -0
  115. /package/dist/test/{services → resources}/oauth2Helper.test.d.ts +0 -0
@@ -8,3 +8,9 @@ export declare let rules: {
8
8
  'no-console': string;
9
9
  };
10
10
  export declare let ignorePatterns: string[];
11
+ export declare let overrides: {
12
+ files: string[];
13
+ rules: {
14
+ '@typescript-eslint/no-floating-promises': string;
15
+ };
16
+ }[];
package/dist/.eslintrc.js CHANGED
@@ -14,7 +14,14 @@ module.exports = {
14
14
  'no-console': 'off',
15
15
  },
16
16
  ignorePatterns: [
17
- 'integrationGenerator/integrationBoilerplate',
18
- 'integrationGenerator/templates',
17
+ 'boilerplate',
18
+ ],
19
+ overrides: [
20
+ {
21
+ 'files': ['test/**/*.test.ts'],
22
+ 'rules': {
23
+ '@typescript-eslint/no-floating-promises': 'off'
24
+ }
25
+ }
19
26
  ],
20
27
  };
@@ -70,9 +70,7 @@ app.use((req: express.Request, res: express.Response, _next: express.NextFunctio
70
70
  });
71
71
 
72
72
  // eslint-disable-next-line
73
- const instance = app.listen(process.env.PORT || 9200, () =>
74
- console.log(`Server started on port ${process.env.PORT || 9200}.`),
75
- );
73
+ const instance = app.listen(process.env.PORT || 9200, () => console.log(`Server started on port ${process.env.PORT || 9200}.`));
76
74
 
77
75
  // Trap exit signals.
78
76
  ['SIGTERM', 'SIGINT', 'SIGUSR2'].forEach(signalType => {
@@ -4,8 +4,8 @@ export default class Activity extends BaseCommand<typeof Activity> {
4
4
  static description: string;
5
5
  static examples: string[];
6
6
  static flags: {
7
- number: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
- environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ number: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
9
9
  follow: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
10
  };
11
11
  catch(error: Error): Promise<void>;
@@ -61,7 +61,7 @@ class Activity extends baseCommand_1.BaseCommand {
61
61
  // Setup the platform client.
62
62
  IntegrationsPlatform.setApiKey(apiKey);
63
63
  IntegrationsPlatform.setEnvironment(environment);
64
- core_1.ux.action.start('Finding the integration');
64
+ core_1.ux.action.start('Finding the integration', undefined, { stdout: true });
65
65
  let integration;
66
66
  try {
67
67
  integration = await IntegrationsPlatform.getIntegrationByName(integrationConfiguration.name);
@@ -77,7 +77,7 @@ class Activity extends baseCommand_1.BaseCommand {
77
77
  }
78
78
  }
79
79
  core_1.ux.action.stop();
80
- core_1.ux.action.start('Retrieving activity');
80
+ core_1.ux.action.start('Retrieving activity', undefined, { stdout: true });
81
81
  let lastEventDate;
82
82
  // eslint-disable-next-line no-constant-condition
83
83
  while (true) {
@@ -5,11 +5,15 @@ export default class Dev extends BaseCommand<typeof Dev> {
5
5
  static examples: string[];
6
6
  catch(error: Error): Promise<void>;
7
7
  static flags: {
8
- environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
9
9
  verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
- crawlMode: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
- checks: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces/parser").CustomOptions>;
12
- 'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
+ 'credential-payload': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ 'credential-id': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ 'test-account': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ 'read-only': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
+ crawlMode: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
15
+ checks: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ 'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
17
  };
14
18
  run(): Promise<void>;
15
19
  }
@@ -9,6 +9,7 @@ const GlobalConfiguration = tslib_1.__importStar(require("../resources/globalCon
9
9
  const integrations_1 = require("../resources/integrations");
10
10
  const configuration_1 = require("../resources/configuration");
11
11
  const decryption_1 = require("../resources/decryption");
12
+ const credentials_1 = require("../resources/credentials");
12
13
  class Dev extends baseCommand_1.BaseCommand {
13
14
  static description = 'Develop your integration';
14
15
  static examples = ['<%= config.bin %> <%= command.id %>'];
@@ -29,6 +30,23 @@ class Dev extends baseCommand_1.BaseCommand {
29
30
  description: 'output more (debug) information',
30
31
  default: false,
31
32
  }),
33
+ 'credential-payload': core_1.Flags.string({
34
+ description: '(advanced) credential payload to use.',
35
+ exclusive: ['credential-id'],
36
+ }),
37
+ 'credential-id': core_1.Flags.integer({
38
+ description: '(advanced) credential to use.',
39
+ exclusive: ['credential-payload'],
40
+ }),
41
+ 'test-account': core_1.Flags.string({
42
+ description: 'test account to use.',
43
+ options: Object.values(configuration_1.CredentialScope),
44
+ default: configuration_1.CredentialScope.DEVELOPMENT,
45
+ }),
46
+ 'read-only': core_1.Flags.boolean({
47
+ description: 'whether or not to only perform read operations',
48
+ allowNo: true,
49
+ }),
32
50
  crawlMode: core_1.Flags.string({
33
51
  description: 'mode to use while crawling the integration graph',
34
52
  options: Object.values(configuration_1.CrawlMode),
@@ -63,23 +81,42 @@ class Dev extends baseCommand_1.BaseCommand {
63
81
  // Resolve the configuration.
64
82
  const environment = flags.environment ?? GlobalConfiguration.Environment.Production;
65
83
  const configuration = await (0, configuration_1.getConfiguration)(environment, flags['config-path']);
66
- let credentials = configuration.testAccounts?.[configuration_1.CredentialScope.DEVELOPMENT];
67
- if (credentials) {
68
- ({ entries: credentials } = await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, credentials));
84
+ let credentialPayload;
85
+ let readOnly = flags['read-only'] ?? false;
86
+ if (flags['credential-id']) {
87
+ const credential = await (0, credentials_1.fetchCredential)(environment, this.config.configDir, flags['credential-id']);
88
+ credentialPayload = JSON.stringify(credential.payload);
89
+ // When "credential-id" is provided, the default value of "read-only" is false.
90
+ readOnly = flags['read-only'] ?? true;
91
+ }
92
+ else if (flags['credential-payload']) {
93
+ credentialPayload = flags['credential-payload'];
94
+ }
95
+ else {
96
+ let credentials = configuration.testAccounts?.[flags['test-account']];
97
+ if (credentials) {
98
+ credentials = (await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, credentials))
99
+ .entries;
100
+ }
101
+ credentialPayload = JSON.stringify(credentials);
69
102
  }
70
103
  let secrets = {};
71
104
  // Decrypt secrets, if necessary.
72
105
  if (configuration.secrets) {
73
- secrets = await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, configuration.secrets);
106
+ secrets = (await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, configuration.secrets))
107
+ .entries;
74
108
  }
75
109
  // Launch the debugger.
76
110
  const commandArguments = [
77
111
  `${process.env.NODE_MODULES_FOLDER}/@unito/integration-debugger/dist/src/index.js`,
78
112
  '--integration-url=http://localhost:9200',
79
113
  `--spawn-process=npm run dev`,
80
- `--credential-payload=${JSON.stringify(credentials)}`,
114
+ `--credential-payload=${credentialPayload}`,
81
115
  `--secrets-payload=${JSON.stringify(secrets)}`,
82
116
  ];
117
+ if (readOnly) {
118
+ commandArguments.push('--read-only');
119
+ }
83
120
  if (configuration.graphRelativeUrl) {
84
121
  commandArguments.push(`--graph-relative-url=${configuration.graphRelativeUrl}`);
85
122
  }
@@ -4,7 +4,7 @@ export default class Encrypt extends BaseCommand<typeof Encrypt> {
4
4
  static description: string;
5
5
  static examples: string[];
6
6
  static flags: {
7
- environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
8
8
  };
9
9
  catch(error: Error): Promise<void>;
10
10
  run(): Promise<void>;
@@ -41,7 +41,7 @@ class Encrypt extends baseCommand_1.BaseCommand {
41
41
  message: 'Enter text to encrypt',
42
42
  type: 'input',
43
43
  });
44
- core_1.ux.action.start('Encrypting data');
44
+ core_1.ux.action.start('Encrypting data', undefined, { stdout: true });
45
45
  const { encryptedData } = await IntegrationsPlatform.encryptData(integrationConfiguration.name, data);
46
46
  core_1.ux.action.stop();
47
47
  core_1.ux.log(`Encrypted Data: ${chalk_1.default.greenBright(encryptedData)}`);
@@ -3,7 +3,7 @@ export default class Init extends BaseCommand<typeof Init> {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
6
+ name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
7
  };
8
8
  catch(error: Error): Promise<void>;
9
9
  run(): Promise<void>;
@@ -5,7 +5,7 @@ const core_1 = require("@oclif/core");
5
5
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
7
7
  const Configuration = tslib_1.__importStar(require("../resources/configuration"));
8
- const integrationGenerator_1 = require("../../integrationGenerator");
8
+ const integrations_1 = require("../resources/integrations");
9
9
  const baseCommand_1 = require("../baseCommand");
10
10
  const errors_1 = require("../errors");
11
11
  class Init extends baseCommand_1.BaseCommand {
@@ -40,8 +40,8 @@ class Init extends baseCommand_1.BaseCommand {
40
40
  .replace(/[^a-z0-9_-]*/g, ''),
41
41
  },
42
42
  ])).name;
43
- core_1.ux.action.start('\nInitializing integration');
44
- const generatedPath = await integrationGenerator_1.Resources.Integration.generateIntegrationSkeleton(name, process.cwd());
43
+ core_1.ux.action.start('\nInitializing integration', undefined, { stdout: true });
44
+ const generatedPath = await (0, integrations_1.copyBoilerplate)(name, process.cwd());
45
45
  process.chdir(generatedPath);
46
46
  await Configuration.writeConfiguration({ name });
47
47
  core_1.ux.action.stop();
@@ -4,7 +4,7 @@ export default class Invite extends BaseCommand<typeof Invite> {
4
4
  static description: string;
5
5
  static examples: string[];
6
6
  static flags: {
7
- environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
8
8
  };
9
9
  catch(error: Error): Promise<void>;
10
10
  run(): Promise<void>;
@@ -55,7 +55,7 @@ class Invite extends baseCommand_1.BaseCommand {
55
55
  type: 'input',
56
56
  },
57
57
  ]);
58
- core_1.ux.action.start('Finding the integration');
58
+ core_1.ux.action.start('Finding the integration', undefined, { stdout: true });
59
59
  let integration;
60
60
  try {
61
61
  integration = await IntegrationsPlatform.getIntegrationByName(integrationConfiguration.name);
@@ -71,7 +71,7 @@ class Invite extends baseCommand_1.BaseCommand {
71
71
  }
72
72
  }
73
73
  core_1.ux.action.stop();
74
- core_1.ux.action.start('Inviting user');
74
+ core_1.ux.action.start('Inviting user', undefined, { stdout: true });
75
75
  await IntegrationsPlatform.inviteUserToIntegration(integration.id, email);
76
76
  core_1.ux.action.stop();
77
77
  core_1.ux.log(`User successfully added! They should now be able to update and publish this integration.`);
@@ -4,7 +4,7 @@ export default class Login extends BaseCommand<typeof Login> {
4
4
  static description: string;
5
5
  static examples: string[];
6
6
  static flags: {
7
- environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
8
8
  };
9
9
  catch(error: Error): Promise<void>;
10
10
  run(): Promise<void>;
@@ -46,7 +46,7 @@ class Login extends baseCommand_1.BaseCommand {
46
46
  this.exit(-1);
47
47
  }
48
48
  // Retrieve the user's profile.
49
- core_1.ux.action.start('Log in...');
49
+ core_1.ux.action.start('Log in', undefined, { stdout: true });
50
50
  let profile = undefined;
51
51
  IntegrationsPlatform.setEnvironment(environment);
52
52
  IntegrationsPlatform.setApiKey(apiKey);
@@ -5,10 +5,10 @@ export default class Oauth2 extends Command {
5
5
  static description: string;
6
6
  static examples: string[];
7
7
  static flags: {
8
- 'test-account': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
- environment: import("@oclif/core/lib/interfaces").OptionFlag<Environment | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ 'test-account': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
10
10
  reauth: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
- 'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
+ 'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
12
  };
13
13
  catch(error: Error): Promise<void>;
14
14
  run(): Promise<void>;
@@ -4,16 +4,22 @@ const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
5
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
6
  const configuration_1 = require("../resources/configuration");
7
- const Oauth2Helper = tslib_1.__importStar(require("../services/oauth2Helper"));
7
+ const Oauth2Helper = tslib_1.__importStar(require("../resources/oauth2Helper"));
8
8
  const IntegrationsPlatform = tslib_1.__importStar(require("../services/integrationsPlatform"));
9
9
  const configurationTypes_1 = require("../configurationTypes");
10
10
  const errors_1 = require("../errors");
11
11
  const globalConfiguration_1 = require("../resources/globalConfiguration");
12
12
  const decryption_1 = require("../resources/decryption");
13
13
  class Oauth2 extends core_1.Command {
14
- static summary = 'Perform an OAuth2 workflow locally';
15
- static description = 'The Oauth2 command allows you to perform an OAuth2 workflow locally, either to create a new test account or to refresh an existing one.';
16
- static examples = ['<%= config.bin %> <%= command.id %>'];
14
+ static summary = `Perform an OAuth2 workflow to either populate or refresh a test account's credentials.`;
15
+ static description = `The Oauth2 command allows you to perform an OAuth2 workflow to populate the specified test account's accessToken and refreshToken to be used by the 'test' and 'dev' commands.
16
+
17
+ If the test-account is already populated, the command will refresh the credentials if the refresh token is available.
18
+ If you want to force a new OAuth2 flow to change the connected account or something else, use the --reauth flag.`;
19
+ static examples = [
20
+ '<%= config.bin %> <%= command.id %>',
21
+ '<%= config.bin %> <%= command.id %> --reauth --test-account=compliance',
22
+ ];
17
23
  static flags = {
18
24
  'test-account': core_1.Flags.string({
19
25
  description: 'Test account to use.',
@@ -24,9 +30,10 @@ class Oauth2 extends core_1.Command {
24
30
  description: 'the environment of the platform',
25
31
  options: Object.values(globalConfiguration_1.Environment),
26
32
  default: globalConfiguration_1.Environment.Production,
33
+ hidden: true,
27
34
  })(),
28
35
  reauth: core_1.Flags.boolean({
29
- description: 'triggers a new oauth2 flow to collect credentials and overwrite the current one',
36
+ description: `triggers a new oauth2 flow to overwrite the test account's current credentials`,
30
37
  default: false,
31
38
  }),
32
39
  'config-path': core_1.Flags.string({
@@ -66,8 +73,8 @@ class Oauth2 extends core_1.Command {
66
73
  const account = testAccount === 'development' ? configuration.testAccounts?.development : configuration.testAccounts?.compliance;
67
74
  let credentials;
68
75
  if (!account || Object.entries(account).length === 0 || flags.reauth) {
69
- core_1.ux.action.start(`Starting Oauth2 flow for account: ${testAccount}`);
70
- credentials = await Oauth2Helper.performOAuth2Flow(oauth2);
76
+ core_1.ux.action.start(`Starting Oauth2 flow for account: ${testAccount}`, undefined, { stdout: true });
77
+ credentials = await Oauth2Helper.performOAuth2Flow(oauth2, environment);
71
78
  core_1.ux.action.stop();
72
79
  }
73
80
  else {
@@ -76,14 +83,12 @@ class Oauth2 extends core_1.Command {
76
83
  return;
77
84
  }
78
85
  const decryptionResult = await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, account);
79
- core_1.ux.action.start(`Refreshing test account ${testAccount}`);
80
- credentials = await Oauth2Helper.updateToken({
81
- ...oauth2,
82
- refreshToken: decryptionResult.entries?.refreshToken,
83
- });
86
+ const refreshToken = decryptionResult.entries?.refreshToken;
87
+ core_1.ux.action.start(`Refreshing test account ${testAccount}`, undefined, { stdout: true });
88
+ credentials = await Oauth2Helper.updateToken(oauth2, refreshToken);
84
89
  // If provider response doesn't contain a new refresh token, use the one we already have
85
90
  if (!credentials.refreshToken) {
86
- credentials.refreshToken = account?.refreshToken;
91
+ credentials.refreshToken = refreshToken;
87
92
  }
88
93
  if (decryptionResult.decryptedKeys.includes('accessToken')) {
89
94
  credentials.accessToken = (await IntegrationsPlatform.encryptData(configuration.name, credentials.accessToken)).encryptedData;
@@ -93,7 +98,7 @@ class Oauth2 extends core_1.Command {
93
98
  }
94
99
  core_1.ux.action.stop();
95
100
  }
96
- core_1.ux.action.start(`Saving credentials for account: ${testAccount}`);
101
+ core_1.ux.action.start(`Saving credentials for account: ${testAccount}`, undefined, { stdout: true });
97
102
  await (0, configuration_1.writeTestAccount)(configuration, credentials, testAccount);
98
103
  core_1.ux.action.stop();
99
104
  return;
@@ -4,11 +4,11 @@ export default class Publish extends BaseCommand<typeof Publish> {
4
4
  static description: string;
5
5
  static examples: string[];
6
6
  static flags: {
7
- environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<GlobalConfiguration.Environment, import("@oclif/core/lib/interfaces").CustomOptions>;
8
8
  'registry-only': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
9
  preview: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
10
  'live-preview': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
- 'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
+ 'config-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
12
  force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
13
  };
14
14
  catch(error: Error): Promise<void>;
@@ -113,7 +113,7 @@ class Publish extends baseCommand_1.BaseCommand {
113
113
  }
114
114
  async livePreviewIntegration(integrationConfiguration) {
115
115
  // Get the profile.
116
- core_1.ux.action.start('Get profile');
116
+ core_1.ux.action.start('Get profile', undefined, { stdout: true });
117
117
  const profile = await IntegrationsPlatform.getProfile();
118
118
  core_1.ux.action.stop();
119
119
  // Generate a new name.
@@ -131,7 +131,7 @@ class Publish extends baseCommand_1.BaseCommand {
131
131
  ].join(' - ');
132
132
  }
133
133
  // Start ngrok & update the base url.
134
- core_1.ux.action.start('Starting ngrok');
134
+ core_1.ux.action.start('Starting ngrok', undefined, { stdout: true });
135
135
  updatedConfiguration.baseUrl = await ngrok_1.default.connect(9200);
136
136
  core_1.ux.action.stop();
137
137
  // Update the registry.
@@ -164,11 +164,11 @@ class Publish extends baseCommand_1.BaseCommand {
164
164
  authorization.instructionsMarkdown = await this.getInstructionsMarkdown(authorization.name);
165
165
  }
166
166
  if (existing) {
167
- core_1.ux.action.start('Integration found. Updating');
167
+ core_1.ux.action.start('Integration found. Updating', undefined, { stdout: true });
168
168
  updated = await IntegrationsPlatform.updateIntegration(existing.id, integrationConfiguration);
169
169
  }
170
170
  else {
171
- core_1.ux.action.start('Integration not found. Creating');
171
+ core_1.ux.action.start('Integration not found. Creating', undefined, { stdout: true });
172
172
  updated = await IntegrationsPlatform.createIntegration(integrationConfiguration);
173
173
  }
174
174
  core_1.ux.action.stop();
@@ -189,7 +189,7 @@ class Publish extends baseCommand_1.BaseCommand {
189
189
  }
190
190
  copyAndMoveToTmpDir() {
191
191
  // Copy integration in tmp folder.
192
- core_1.ux.action.start('Packaging');
192
+ core_1.ux.action.start('Packaging', undefined, { stdout: true });
193
193
  const archivePath = this.archiveIntegration();
194
194
  const tmpDir = tmp_1.default.dirSync();
195
195
  child_process_1.default.execSync(`unzip ${archivePath} -d ${tmpDir.name}`);
@@ -199,14 +199,14 @@ class Publish extends baseCommand_1.BaseCommand {
199
199
  }
200
200
  async previewIntegration(integrationConfiguration) {
201
201
  // Get the profile.
202
- core_1.ux.action.start('Get profile');
202
+ core_1.ux.action.start('Get profile', undefined, { stdout: true });
203
203
  const profile = await IntegrationsPlatform.getProfile();
204
204
  core_1.ux.action.stop();
205
205
  // Generate a new name.
206
206
  const newName = `${integrationConfiguration.name}-preview-${this.hashEmail(profile.email)}`;
207
207
  // Update the secrets.
208
208
  const updatedConfiguration = await this.generateNewSecrets(integrationConfiguration, newName);
209
- core_1.ux.action.start('Creating preview');
209
+ core_1.ux.action.start('Creating preview', undefined, { stdout: true });
210
210
  // Update the name.
211
211
  updatedConfiguration.name = newName;
212
212
  // Update the display name.
@@ -225,20 +225,20 @@ class Publish extends baseCommand_1.BaseCommand {
225
225
  }
226
226
  async publishIntegration(integrationConfiguration) {
227
227
  // Packaging the integration.
228
- core_1.ux.action.start('Packaging');
228
+ core_1.ux.action.start('Packaging', undefined, { stdout: true });
229
229
  // Write the final configuration on disk.
230
230
  await IntegrationConfiguration.writeConfiguration(integrationConfiguration);
231
231
  const archivePath = this.archiveIntegration();
232
232
  core_1.ux.action.stop();
233
233
  // Publish the integration.
234
- core_1.ux.action.start('Publishing');
234
+ core_1.ux.action.start('Publishing', undefined, { stdout: true });
235
235
  await IntegrationsPlatform.publishIntegration(archivePath);
236
236
  core_1.ux.action.stop();
237
237
  // Summary of the operation.
238
238
  core_1.ux.log('');
239
239
  core_1.ux.log(['Your integration', gradient.fruit(integrationConfiguration.name), 'is being published.'].join(' '));
240
- core_1.ux.log(chalk_1.default.yellowBright("Note that if the code of your integration did not change, it won't be republished."));
241
- core_1.ux.log(chalk_1.default.blueBright(`You can follow the publishing of ${gradient.fruit(integrationConfiguration.name)} by running the command ${chalk_1.default.yellowBright('integration-cli activity --follow')}.`));
240
+ core_1.ux.log("Note that if the code of your integration did not change, it won't be republished.");
241
+ core_1.ux.log(chalk_1.default.blueBright(`To follow the publication, execute ${chalk_1.default.yellowBright('integration-cli activity --follow')}.`));
242
242
  }
243
243
  indent(paragraph, tabs = 1) {
244
244
  return paragraph
@@ -258,7 +258,7 @@ class Publish extends baseCommand_1.BaseCommand {
258
258
  return crypto_1.default.createHash('shake256', { outputLength: 2 }).update(email).digest('hex');
259
259
  }
260
260
  async generateNewSecrets(integrationConfiguration, newIntegrationName) {
261
- core_1.ux.action.start(`Reencrypting with name ${newIntegrationName}`);
261
+ core_1.ux.action.start(`Reencrypting with name ${newIntegrationName}`, undefined, { stdout: true });
262
262
  const updatedConfiguration = JSON.parse(JSON.stringify(integrationConfiguration)); // deep copy.
263
263
  for (const authorization of updatedConfiguration.authorizations ?? []) {
264
264
  /* istanbul ignore if */
@@ -10,6 +10,7 @@ const GlobalConfiguration = tslib_1.__importStar(require("../resources/globalCon
10
10
  const integrations_1 = require("../resources/integrations");
11
11
  const configuration_1 = require("../resources/configuration");
12
12
  const decryption_1 = require("../resources/decryption");
13
+ const credentials_1 = require("../resources/credentials");
13
14
  class Test extends baseCommand_1.BaseCommand {
14
15
  static description = 'Test your integration';
15
16
  static examples = ['<%= config.bin %> <%= command.id %>'];
@@ -36,13 +37,22 @@ class Test extends baseCommand_1.BaseCommand {
36
37
  description: 'output report in JSON format at the specified path',
37
38
  }),
38
39
  'credential-payload': core_1.Flags.string({
40
+ description: '(advanced) credential payload to use.',
41
+ exclusive: ['credential-id'],
42
+ }),
43
+ 'credential-id': core_1.Flags.integer({
39
44
  description: '(advanced) credential to use.',
45
+ exclusive: ['credential-payload'],
40
46
  }),
41
47
  'test-account': core_1.Flags.string({
42
- description: 'Test account to use.',
48
+ description: 'test account to use.',
43
49
  options: Object.values(configuration_1.CredentialScope),
44
50
  default: configuration_1.CredentialScope.DEVELOPMENT,
45
51
  }),
52
+ 'read-only': core_1.Flags.boolean({
53
+ description: 'whether or not to only perform read operations',
54
+ allowNo: true,
55
+ }),
46
56
  crawlMode: core_1.Flags.string({
47
57
  description: 'mode to use while crawling the integration graph',
48
58
  options: Object.values(configuration_1.CrawlMode),
@@ -54,13 +64,13 @@ class Test extends baseCommand_1.BaseCommand {
54
64
  default: [],
55
65
  }),
56
66
  debug: core_1.Flags.boolean({
57
- description: 'Log launch command to console before running it - including decrypted values - for debugging only',
67
+ description: 'log launch command to console before running it - including decrypted values - for debugging only',
58
68
  hidden: true,
59
69
  default: false,
60
70
  }),
61
71
  'config-path': core_1.Flags.string({
62
72
  summary: 'relative path to a custom ".unito.json" file',
63
- description: `Use a custom configuration file instead of the default '.unito.json' or other environment specific
73
+ description: `use a custom configuration file instead of the default '.unito.json' or other environment specific
64
74
  ones.
65
75
 
66
76
  If you want to force the CLI to use a specific configuration file, you can use this flag to specify the relative
@@ -89,19 +99,30 @@ class Test extends baseCommand_1.BaseCommand {
89
99
  // Resolve the configuration.
90
100
  const environment = flags.environment ?? GlobalConfiguration.Environment.Production;
91
101
  const configuration = await (0, configuration_1.getConfiguration)(environment, flags['config-path']);
92
- let credentialPayload = flags['credential-payload'];
93
- // Default to test account's credentials if none are specifically provided
94
- if (credentialPayload === null || credentialPayload === undefined) {
102
+ let credentialPayload;
103
+ let readOnly = flags['read-only'] ?? false;
104
+ if (flags['credential-id']) {
105
+ const credential = await (0, credentials_1.fetchCredential)(environment, this.config.configDir, flags['credential-id']);
106
+ credentialPayload = JSON.stringify(credential.payload);
107
+ // When "credential-id" is provided, the default value of "read-only" is false.
108
+ readOnly = flags['read-only'] ?? true;
109
+ }
110
+ else if (flags['credential-payload']) {
111
+ credentialPayload = flags['credential-payload'];
112
+ }
113
+ else {
95
114
  let credentials = configuration.testAccounts?.[flags['test-account']];
96
115
  if (credentials) {
97
- ({ entries: credentials } = await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, credentials));
116
+ credentials = (await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, credentials))
117
+ .entries;
98
118
  }
99
119
  credentialPayload = JSON.stringify(credentials);
100
120
  }
101
121
  let secrets = {};
102
122
  // Decrypt secrets, if necessary.
103
123
  if (configuration.secrets) {
104
- secrets = await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, configuration.secrets);
124
+ secrets = (await (0, decryption_1.decryptEntries)(configuration.name, environment, this.config.configDir, configuration.secrets))
125
+ .entries;
105
126
  }
106
127
  // Launch the tests.
107
128
  const commandArguments = [
@@ -114,6 +135,9 @@ class Test extends baseCommand_1.BaseCommand {
114
135
  `--starting-path=${flags['starting-path']}`,
115
136
  `--starting-operation=${flags['starting-operation']}`,
116
137
  ];
138
+ if (readOnly) {
139
+ commandArguments.push('--read-only');
140
+ }
117
141
  if (configuration.graphRelativeUrl) {
118
142
  commandArguments.push(`--graph-relative-url=${configuration.graphRelativeUrl}`);
119
143
  }
@@ -26,7 +26,7 @@ class Upgrade extends baseCommand_1.BaseCommand {
26
26
  //
27
27
  // Current version
28
28
  //
29
- core_1.ux.action.start('Checking the current version');
29
+ core_1.ux.action.start('Checking the current version', undefined, { stdout: true });
30
30
  const currentVersion = child_process_1.default
31
31
  .execSync(`npm list ${npmOptions} --depth 0 | grep ${packageName} | sed "s/.*@\\([^@]*\\)$/\\1/"`, execOptions)
32
32
  .toString()
@@ -35,7 +35,7 @@ class Upgrade extends baseCommand_1.BaseCommand {
35
35
  //
36
36
  // Next version
37
37
  //
38
- core_1.ux.action.start('Checking the available version');
38
+ core_1.ux.action.start('Checking the available version', undefined, { stdout: true });
39
39
  const newVersion = child_process_1.default
40
40
  .execSync(`npm show ${npmOptions} ${packageName} version`, execOptions)
41
41
  .toString()
@@ -51,7 +51,7 @@ class Upgrade extends baseCommand_1.BaseCommand {
51
51
  //
52
52
  // Validate / Upgrade the package globally.
53
53
  //
54
- core_1.ux.action.start(`${latestVersion ? 'Validating' : 'Upgrading'} the package`);
54
+ core_1.ux.action.start(`${latestVersion ? 'Validating' : 'Upgrading'} the package`, undefined, { stdout: true });
55
55
  // To make sure we have a clean version of the CLI, with updated packages, we force the re-installation.
56
56
  child_process_1.default.execSync(`npm install --force ${npmOptions} ${packageName}`, {
57
57
  ...execOptions,
@@ -21,6 +21,14 @@ export declare class AuthenticationFailed extends Error {
21
21
  }
22
22
  export declare class DecryptionAuthenticationError extends Error {
23
23
  }
24
+ export declare class UnsupportedContentTypeError extends Error {
25
+ }
26
+ export declare class CredentialAuthenticationError extends Error {
27
+ }
28
+ export declare class CredentialAccessDenied extends Error {
29
+ }
30
+ export declare class IntegrationAlreadyExistsError extends Error {
31
+ }
24
32
  export declare class EntryDecryptionError extends Error {
25
33
  key: string;
26
34
  value: string;