@unito/integration-cli 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,47 +1,42 @@
1
- import tseslint from '@typescript-eslint/eslint-plugin';
2
- import tsParser from '@typescript-eslint/parser';
1
+ import eslint from '@eslint/js';
2
+ import tseslint from 'typescript-eslint';
3
3
 
4
- export default [
4
+ export default tseslint.config(
5
5
  {
6
6
  ignores: ['node_modules/**', 'dist/**', 'eslint.config.mjs'],
7
7
  },
8
+ eslint.configs.recommended,
9
+ ...tseslint.configs.recommendedTypeChecked,
8
10
  {
9
- files: ['**/*.{js,ts}'],
10
11
  languageOptions: {
11
- parser: tsParser,
12
12
  parserOptions: {
13
13
  project: './**/tsconfig.json',
14
14
  },
15
- ecmaVersion: 'latest',
16
- sourceType: 'module',
17
15
  globals: {
18
- // Equivalent to env: { browser: true, node: true, es6: true }
19
- window: 'readonly',
20
- document: 'readonly',
21
- navigator: 'readonly',
22
16
  process: 'readonly',
23
17
  require: 'readonly',
24
18
  module: 'readonly',
25
19
  __dirname: 'readonly',
26
20
  },
27
21
  },
28
- plugins: {
29
- '@typescript-eslint': tseslint,
30
- },
31
22
  rules: {
32
- // TypeScript rules
33
- '@typescript-eslint/no-loss-of-precision': 'off',
34
- '@typescript-eslint/no-explicit-any': 'off',
35
- '@typescript-eslint/ban-ts-comment': 'off',
36
- '@typescript-eslint/ban-ts-ignore': 'off',
37
- '@typescript-eslint/explicit-module-boundary-types': 'off',
38
- '@typescript-eslint/no-var-requires': 'off',
39
- '@typescript-eslint/no-floating-promises': 'error',
40
- '@typescript-eslint/no-unused-vars': 'off',
41
- '@typescript-eslint/no-non-null-assertion': 'off',
42
- '@typescript-eslint/prefer-namespace-keyword': 'off',
43
- '@typescript-eslint/no-namespace': 'off',
44
- '@typescript-eslint/no-inferrable-types': 'off',
23
+ 'no-undef': 'off',
24
+ '@typescript-eslint/no-unused-vars': [
25
+ 'error',
26
+ {
27
+ argsIgnorePattern: '^_',
28
+ varsIgnorePattern: '^_',
29
+ caughtErrorsIgnorePattern: '^_',
30
+ },
31
+ ],
32
+ '@typescript-eslint/no-misused-promises': [
33
+ 'error',
34
+ {
35
+ checksVoidReturn: {
36
+ arguments: false,
37
+ },
38
+ },
39
+ ],
45
40
  '@typescript-eslint/naming-convention': [
46
41
  'warn',
47
42
  {
@@ -59,14 +54,8 @@ export default [
59
54
  modifiers: ['requiresQuotes'],
60
55
  },
61
56
  ],
62
-
63
- // JavaScript rules
64
57
  'no-whitespace-before-property': 'error',
65
58
  'no-trailing-spaces': 'error',
66
- 'no-extra-boolean-cast': 'off',
67
- 'no-inner-declarations': 'off',
68
- 'no-useless-escape': 'off',
69
- 'no-case-declarations': 'off',
70
59
  'space-unary-ops': [
71
60
  'error',
72
61
  {
@@ -83,13 +72,26 @@ export default [
83
72
  },
84
73
  ],
85
74
  'object-curly-spacing': ['error', 'always'],
86
- 'no-console': ['error', { allow: ['info', 'error'] }],
75
+ 'no-console': 'error',
76
+ curly: ['error', 'all'],
77
+ 'padding-line-between-statements': ['error', { blankLine: 'always', prev: '*', next: 'return' }],
78
+ eqeqeq: ['error', 'always', { null: 'ignore' }],
79
+ 'prefer-const': 'error',
80
+ 'no-else-return': 'error',
87
81
  },
88
82
  },
89
83
  {
90
84
  files: ['test/**/*.test.ts'],
91
85
  rules: {
92
86
  '@typescript-eslint/no-floating-promises': 'off',
87
+ '@typescript-eslint/no-explicit-any': 'off',
88
+ '@typescript-eslint/no-unsafe-assignment': 'off',
89
+ '@typescript-eslint/no-unsafe-member-access': 'off',
90
+ '@typescript-eslint/no-unsafe-call': 'off',
91
+ '@typescript-eslint/no-unsafe-argument': 'off',
92
+ '@typescript-eslint/no-unsafe-return': 'off',
93
+ '@typescript-eslint/unbound-method': 'off',
94
+ '@typescript-eslint/require-await': 'off',
93
95
  },
94
96
  },
95
- ];
97
+ );
@@ -1786,10 +1786,11 @@
1786
1786
  }
1787
1787
  },
1788
1788
  "node_modules/flatted": {
1789
- "version": "3.3.1",
1790
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
1791
- "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
1792
- "dev": true
1789
+ "version": "3.4.2",
1790
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
1791
+ "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
1792
+ "dev": true,
1793
+ "license": "ISC"
1793
1794
  },
1794
1795
  "node_modules/form-data": {
1795
1796
  "version": "4.0.4",
@@ -88,6 +88,10 @@ class Test extends baseCommand_1.BaseCommand {
88
88
  allowNo: true,
89
89
  default: false,
90
90
  }),
91
+ port: core_1.Flags.integer({
92
+ description: 'port to run the integration on',
93
+ default: 9200,
94
+ }),
91
95
  };
92
96
  async catch(error) {
93
97
  /* istanbul ignore if */
@@ -159,7 +163,7 @@ class Test extends baseCommand_1.BaseCommand {
159
163
  // Launch the tests.
160
164
  const commandArguments = [
161
165
  `${process.env.NODE_MODULES_FOLDER}/@unito/integration-debugger/dist/src/index.js`,
162
- '--integration-url=http://localhost:9200',
166
+ `--integration-url=http://localhost:${flags.port}`,
163
167
  '--spawn-process=npm run dev',
164
168
  `--credential-payload=${credentialPayload}`,
165
169
  `--secrets-payload=${JSON.stringify(secrets)}`,
@@ -211,7 +215,7 @@ class Test extends baseCommand_1.BaseCommand {
211
215
  const child = child_process_1.default.spawn('node', commandArguments, {
212
216
  detached: true,
213
217
  stdio: 'inherit',
214
- env: { ...process.env, ...environmentVariables, NODE_ENV: 'development', PORT: '9200' },
218
+ env: { ...process.env, ...environmentVariables, NODE_ENV: 'development', PORT: String(flags.port) },
215
219
  });
216
220
  // istanbul ignore next
217
221
  child.on('exit', (code) => {
@@ -3,9 +3,66 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.performOAuth2Flow = performOAuth2Flow;
4
4
  exports.updateToken = updateToken;
5
5
  const tslib_1 = require("tslib");
6
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
+ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
6
8
  const oauth2_1 = tslib_1.__importDefault(require("../services/oauth2"));
7
9
  const errors_1 = require("../errors");
8
10
  const globalConfiguration_1 = require("./globalConfiguration");
11
+ async function isServiceReachable(url) {
12
+ try {
13
+ await fetch(url, { signal: AbortSignal.timeout(3000) });
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ async function waitForLegacyRedirectServices(legacyRedirectUrl) {
21
+ const { origin, port } = new URL(legacyRedirectUrl);
22
+ const services = [
23
+ {
24
+ name: 'maestro',
25
+ healthUrl: `${origin}/health`,
26
+ port: port || '3000',
27
+ startCmd: 'cd console/maestro && npm run dev',
28
+ },
29
+ {
30
+ name: 'platformServer',
31
+ healthUrl: 'http://127.0.0.1:9000/health',
32
+ port: '9000',
33
+ startCmd: 'cd connector-service/platformServer && npm run dev',
34
+ },
35
+ ];
36
+ console.log(chalk_1.default.yellow('\n This integration uses legacyRedirectUrl — additional services are required.'));
37
+ console.log(chalk_1.default.yellow(' The OAuth callback will be routed through maestro → platformServer → CLI.\n'));
38
+ let allUp = false;
39
+ while (!allUp) {
40
+ const results = await Promise.all(services.map(s => isServiceReachable(s.healthUrl)));
41
+ allUp = results.every(Boolean);
42
+ for (const [i, service] of services.entries()) {
43
+ if (results[i]) {
44
+ console.log(chalk_1.default.green(` ✓ ${service.name} is running`));
45
+ }
46
+ else {
47
+ console.log(chalk_1.default.red(` ✗ ${service.name} not running on port ${service.port}`));
48
+ console.log(` Start it: ${service.startCmd}`);
49
+ }
50
+ }
51
+ if (allUp) {
52
+ console.log('');
53
+ break;
54
+ }
55
+ const { retry } = await inquirer_1.default.prompt({
56
+ name: 'retry',
57
+ type: 'confirm',
58
+ message: 'Start the missing services and try again?',
59
+ default: true,
60
+ });
61
+ if (!retry) {
62
+ throw new Error('OAuth2 flow aborted: required services are not running.');
63
+ }
64
+ }
65
+ }
9
66
  async function performOAuth2Flow(applicationCredentials, environment = globalConfiguration_1.Environment.Production, credentialPayload) {
10
67
  const oauthHelper = new oauth2_1.default(applicationCredentials, environment, credentialPayload);
11
68
  const serverUrl = await oauthHelper.startServer();
@@ -14,6 +71,9 @@ async function performOAuth2Flow(applicationCredentials, environment = globalCon
14
71
  const error = await healthCheck.text();
15
72
  throw new Error(`OAuthServer did not start correctly.\n HealthCheck status: ${healthCheck.status}\n Response: ${error}`);
16
73
  }
74
+ if (applicationCredentials.legacyRedirectUrl) {
75
+ await waitForLegacyRedirectServices(applicationCredentials.legacyRedirectUrl);
76
+ }
17
77
  await oauthHelper.authorize();
18
78
  const oauth2Response = await oauthHelper.callbackIsDone();
19
79
  await oauthHelper.stopServer();
@@ -72,6 +72,15 @@ describe('Test', () => {
72
72
  .command(['test'])
73
73
  .exit(-1)
74
74
  .it('handled exception');
75
+ test_1.test
76
+ .stdout()
77
+ .stub(ConfigurationResource, 'getConfiguration', stub => stub.resolves(cliConfiguration))
78
+ .stub(IntegrationResource, 'validateIsIntegrationDirectory', stub => stub.returns(true))
79
+ .command(['test', '--port=9300'])
80
+ .it('custom port', () => {
81
+ (0, test_1.expect)(spawnStub.getCall(0).args.at(1)).to.include('--integration-url=http://localhost:9300');
82
+ (0, test_1.expect)(spawnStub.getCall(0).args.at(2).env.PORT).to.equal('9300');
83
+ });
75
84
  test_1.test
76
85
  .stdout()
77
86
  .stub(ConfigurationResource, 'getConfiguration', stub => stub.resolves(cliConfiguration))
@@ -948,6 +948,14 @@
948
948
  "name": "skip-install",
949
949
  "allowNo": true,
950
950
  "type": "boolean"
951
+ },
952
+ "port": {
953
+ "description": "port to run the integration on",
954
+ "name": "port",
955
+ "default": 9200,
956
+ "hasDynamicHelp": false,
957
+ "multiple": false,
958
+ "type": "option"
951
959
  }
952
960
  },
953
961
  "hasDynamicHelp": false,
@@ -999,5 +1007,5 @@
999
1007
  ]
1000
1008
  }
1001
1009
  },
1002
- "version": "1.0.0"
1010
+ "version": "1.0.2"
1003
1011
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unito/integration-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Integration CLI",
5
5
  "bin": {
6
6
  "integration-cli": "./bin/run"
@@ -36,10 +36,10 @@
36
36
  "!/bin/dev*"
37
37
  ],
38
38
  "dependencies": {
39
- "@ngrok/ngrok": "^1.4.1",
39
+ "@ngrok/ngrok": "^1.7.0",
40
40
  "@oazapfts/runtime": "1.x",
41
41
  "@oclif/core": "3.x",
42
- "@unito/integration-debugger": "0.29.0",
42
+ "@unito/integration-debugger": "^0.29.1",
43
43
  "ajv": "8.x",
44
44
  "ajv-formats": "3.x",
45
45
  "better-ajv-errors": "1.x",