@redocly/cli 1.0.0-beta.129 → 1.0.0-beta.130

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const fetch_with_timeout_1 = require("../fetch-with-timeout");
13
+ const node_fetch_1 = require("node-fetch");
14
+ jest.mock('node-fetch');
15
+ describe('fetchWithTimeout', () => {
16
+ afterEach(() => {
17
+ jest.clearAllMocks();
18
+ });
19
+ it('should use bare node-fetch if AbortController is not available', () => __awaiter(void 0, void 0, void 0, function* () {
20
+ // @ts-ignore
21
+ global.AbortController = undefined;
22
+ // @ts-ignore
23
+ global.setTimeout = jest.fn();
24
+ yield fetch_with_timeout_1.default('url', { method: 'GET' });
25
+ expect(node_fetch_1.default).toHaveBeenCalledWith('url', { method: 'GET' });
26
+ expect(global.setTimeout).toHaveBeenCalledTimes(0);
27
+ }));
28
+ it('should call node-fetch with signal if AbortController is available', () => __awaiter(void 0, void 0, void 0, function* () {
29
+ global.AbortController = jest.fn().mockImplementation(() => ({ signal: 'something' }));
30
+ // @ts-ignore
31
+ global.setTimeout = jest.fn();
32
+ global.clearTimeout = jest.fn();
33
+ yield fetch_with_timeout_1.default('url');
34
+ expect(global.setTimeout).toHaveBeenCalledTimes(1);
35
+ expect(node_fetch_1.default).toHaveBeenCalledWith('url', { signal: 'something' });
36
+ expect(global.clearTimeout).toHaveBeenCalledTimes(1);
37
+ }));
38
+ });
@@ -399,16 +399,23 @@ describe('cleanArgs', () => {
399
399
  beforeEach(() => {
400
400
  // @ts-ignore
401
401
  openapi_core_1.isAbsoluteUrl = jest.requireActual('@redocly/openapi-core').isAbsoluteUrl;
402
+ // @ts-ignore
403
+ fs_1.existsSync = (value) => jest.requireActual('fs').existsSync(path.resolve(__dirname, value));
404
+ // @ts-ignore
405
+ fs_1.statSync = (value) => jest.requireActual('fs').statSync(path.resolve(__dirname, value));
406
+ });
407
+ afterEach(() => {
408
+ jest.clearAllMocks();
402
409
  });
403
410
  it('should remove potentially sensitive data from args', () => {
404
411
  const testArgs = {
405
- config: 'some-folder/redocly.yaml',
406
- apis: ['main@v1', 'openapi.yaml', 'http://some.url/openapi.yaml'],
412
+ config: './fixtures/redocly.yaml',
413
+ apis: ['main@v1', 'fixtures/openapi.yaml', 'http://some.url/openapi.yaml'],
407
414
  format: 'codeframe',
408
415
  };
409
416
  expect(utils_1.cleanArgs(testArgs)).toEqual({
410
- config: '***.yaml',
411
- apis: ['main@v1', '***.yaml', 'http://***'],
417
+ config: 'file-yaml',
418
+ apis: ['api-name@api-version', 'file-yaml', 'http://url'],
412
419
  format: 'codeframe',
413
420
  });
414
421
  });
@@ -417,22 +424,46 @@ describe('cleanArgs', () => {
417
424
  destination: '@org/name@version',
418
425
  };
419
426
  expect(utils_1.cleanArgs(testArgs)).toEqual({
420
- destination: '@***/name@version',
427
+ destination: '@organization/api-name@api-version',
421
428
  });
422
429
  });
423
430
  });
424
431
  describe('cleanRawInput', () => {
425
- it('should remove potentially sensitive data from raw CLI input', () => {
432
+ beforeEach(() => {
426
433
  // @ts-ignore
427
434
  openapi_core_1.isAbsoluteUrl = jest.requireActual('@redocly/openapi-core').isAbsoluteUrl;
435
+ // @ts-ignore
436
+ fs_1.existsSync = (value) => jest.requireActual('fs').existsSync(path.resolve(__dirname, value));
437
+ // @ts-ignore
438
+ fs_1.statSync = (value) => jest.requireActual('fs').statSync(path.resolve(__dirname, value));
439
+ });
440
+ afterEach(() => {
441
+ jest.clearAllMocks();
442
+ });
443
+ it('should remove potentially sensitive data from raw CLI input', () => {
428
444
  const rawInput = [
429
445
  'redocly',
430
- 'lint',
431
- 'main@v1',
432
- 'openapi.yaml',
446
+ 'bundle',
447
+ 'api-name@api-version',
448
+ './fixtures/openapi.yaml',
433
449
  'http://some.url/openapi.yaml',
434
- '--config=some-folder/redocly.yaml',
450
+ '--config=fixtures/redocly.yaml',
451
+ '--output',
452
+ 'fixtures',
453
+ ];
454
+ expect(utils_1.cleanRawInput(rawInput)).toEqual('redocly bundle api-name@api-version file-yaml http://url --config=file-yaml --output folder');
455
+ });
456
+ it('should preserve safe data from raw CLI input', () => {
457
+ const rawInput = [
458
+ 'redocly',
459
+ 'lint',
460
+ './fixtures/openapi.json',
461
+ '--format',
462
+ 'stylish',
463
+ '--extends=minimal',
464
+ '--skip-rule',
465
+ 'operation-4xx-response',
435
466
  ];
436
- expect(utils_1.cleanRawInput(rawInput)).toEqual('redocly lint main@v1 ***.yaml http://*** --config=***.yaml');
467
+ expect(utils_1.cleanRawInput(rawInput)).toEqual('redocly lint file-json --format stylish --extends=minimal --skip-rule operation-4xx-response');
437
468
  });
438
469
  });
@@ -13,6 +13,7 @@ const utils_1 = require("../utils");
13
13
  const process = require("process");
14
14
  const wrapper_1 = require("../wrapper");
15
15
  const lint_1 = require("../commands/lint");
16
+ const push_1 = require("../commands/push");
16
17
  jest.mock('node-fetch');
17
18
  jest.mock('../utils', () => ({
18
19
  sendTelemetry: jest.fn(),
@@ -44,4 +45,13 @@ describe('commandWrapper', () => {
44
45
  expect(lint_1.handleLint).toHaveBeenCalledTimes(1);
45
46
  expect(utils_1.sendTelemetry).toHaveBeenCalledTimes(0);
46
47
  }));
48
+ it('should pass files from arguments to config', () => __awaiter(void 0, void 0, void 0, function* () {
49
+ const filesToPush = ['test1.yaml', 'test2.yaml'];
50
+ const loadConfigMock = utils_1.loadConfigAndHandleErrors;
51
+ const argv = {
52
+ files: filesToPush,
53
+ };
54
+ yield wrapper_1.commandWrapper(push_1.handlePush)(argv);
55
+ expect(loadConfigMock).toHaveBeenCalledWith(expect.objectContaining({ files: filesToPush }));
56
+ }));
47
57
  });
@@ -0,0 +1,2 @@
1
+ declare const _default: (url: string, options?: {}) => Promise<import("node-fetch").Response>;
2
+ export default _default;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const node_fetch_1 = require("node-fetch");
13
+ const TIMEOUT = 3000;
14
+ exports.default = (url, options = {}) => __awaiter(void 0, void 0, void 0, function* () {
15
+ if (!global.AbortController) {
16
+ return node_fetch_1.default(url, options);
17
+ }
18
+ const controller = new AbortController();
19
+ const timeout = setTimeout(() => {
20
+ controller.abort();
21
+ }, TIMEOUT);
22
+ const res = yield node_fetch_1.default(url, Object.assign({ signal: controller.signal }, options));
23
+ clearTimeout(timeout);
24
+ return res;
25
+ });
@@ -15,7 +15,7 @@ const os_1 = require("os");
15
15
  const path_1 = require("path");
16
16
  const fs_1 = require("fs");
17
17
  const semver_1 = require("semver");
18
- const node_fetch_1 = require("node-fetch");
18
+ const fetch_with_timeout_1 = require("./fetch-with-timeout");
19
19
  const colorette_1 = require("colorette");
20
20
  const utils_1 = require("./utils");
21
21
  _a = require('../package.json'), exports.version = _a.version, exports.name = _a.name;
@@ -41,7 +41,7 @@ exports.notifyUpdateCliVersion = notifyUpdateCliVersion;
41
41
  const isNewVersionAvailable = (current, latest) => semver_1.compare(current, latest) < 0;
42
42
  const getLatestVersion = (packageName) => __awaiter(void 0, void 0, void 0, function* () {
43
43
  const latestUrl = `http://registry.npmjs.org/${packageName}/latest`;
44
- const response = yield node_fetch_1.default(latestUrl);
44
+ const response = yield fetch_with_timeout_1.default(latestUrl);
45
45
  const info = yield response.json();
46
46
  return info.version;
47
47
  });
package/lib/utils.d.ts CHANGED
@@ -54,6 +54,7 @@ export declare type Analytics = {
54
54
  version: string;
55
55
  exit_code: ExitCode;
56
56
  environment?: string;
57
+ environment_ci?: string;
57
58
  raw_input: string;
58
59
  has_config?: boolean;
59
60
  };
package/lib/utils.js CHANGED
@@ -21,7 +21,7 @@ var __rest = (this && this.__rest) || function (s, e) {
21
21
  };
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  exports.cleanRawInput = exports.cleanArgs = exports.sendTelemetry = exports.cleanColors = exports.checkIfRulesetExist = exports.sortTopLevelKeysForOas = exports.loadConfigAndHandleErrors = exports.isSubdir = exports.exitWithError = exports.printUnusedWarnings = exports.getOutputFileName = exports.printConfigLintTotals = exports.printLintTotals = exports.HandledError = exports.handleError = exports.pluralize = exports.writeYaml = exports.readYaml = exports.promptUser = exports.saveBundle = exports.dumpBundle = exports.CircularJSONNotSupportedError = exports.langToExt = exports.escapeLanguageName = exports.pathToFilename = exports.printExecutionTime = exports.getExecutionTime = exports.getFallbackApisOrExit = void 0;
24
- const node_fetch_1 = require("node-fetch");
24
+ const fetch_with_timeout_1 = require("./fetch-with-timeout");
25
25
  const path_1 = require("path");
26
26
  const colorette_1 = require("colorette");
27
27
  const perf_hooks_1 = require("perf_hooks");
@@ -417,7 +417,6 @@ function sendTelemetry(argv, exit_code, has_config) {
417
417
  const { _: [command], $0: _ } = argv, args = __rest(argv, ["_", "$0"]);
418
418
  const event_time = new Date().toISOString();
419
419
  const redoclyClient = new openapi_core_1.RedoclyClient();
420
- const node_version = process.version;
421
420
  const logged_in = yield redoclyClient.isAuthorizedWithRedoclyByRegion();
422
421
  const data = {
423
422
  event: 'cli_command',
@@ -425,14 +424,15 @@ function sendTelemetry(argv, exit_code, has_config) {
425
424
  logged_in,
426
425
  command,
427
426
  arguments: cleanArgs(args),
428
- node_version,
427
+ node_version: process.version,
429
428
  version: update_version_notifier_1.version,
430
429
  exit_code,
431
430
  environment: process.env.REDOCLY_ENVIRONMENT,
431
+ environment_ci: process.env.CI,
432
432
  raw_input: cleanRawInput(process.argv.slice(2)),
433
433
  has_config,
434
434
  };
435
- yield node_fetch_1.default(`https://api.redocly.com/registry/telemetry/cli`, {
435
+ yield fetch_with_timeout_1.default(`https://api.redocly.com/registry/telemetry/cli`, {
436
436
  method: 'POST',
437
437
  headers: {
438
438
  'content-type': 'application/json',
@@ -446,18 +446,27 @@ function sendTelemetry(argv, exit_code, has_config) {
446
446
  });
447
447
  }
448
448
  exports.sendTelemetry = sendTelemetry;
449
+ function isFile(value) {
450
+ return fs.existsSync(value) && fs.statSync(value).isFile();
451
+ }
452
+ function isDirectory(value) {
453
+ return fs.existsSync(value) && fs.statSync(value).isDirectory();
454
+ }
449
455
  function cleanString(value) {
450
456
  if (!value) {
451
457
  return value;
452
458
  }
453
459
  if (openapi_core_1.isAbsoluteUrl(value)) {
454
- return value.split('://')[0] + '://***';
460
+ return value.split('://')[0] + '://url';
461
+ }
462
+ if (isFile(value)) {
463
+ return value.replace(/.+\.([^.]+)$/, (_, ext) => 'file-' + ext);
455
464
  }
456
- if (value.endsWith('.json') || value.endsWith('.yaml') || value.endsWith('.yml')) {
457
- return value.replace(/^(.*)\.(yaml|yml|json)$/gi, (_, __, ext) => '***.' + ext);
465
+ if (isDirectory(value)) {
466
+ return 'folder';
458
467
  }
459
468
  if (push_1.DESTINATION_REGEX.test(value)) {
460
- return value.replace(/^@[\w\-\s]+\//, () => '@***/');
469
+ return value.startsWith('@') ? '@organization/api-name@api-version' : 'api-name@api-version';
461
470
  }
462
471
  return value;
463
472
  }
package/lib/wrapper.js CHANGED
@@ -27,7 +27,7 @@ function commandWrapper(commandHandler) {
27
27
  configPath: argv.config,
28
28
  customExtends: argv.extends,
29
29
  region: argv.region,
30
- files: argv.file,
30
+ files: argv.files,
31
31
  processRawConfig: lint_1.lintConfigCallback(argv, update_version_notifier_1.version),
32
32
  }));
33
33
  telemetry = config.telemetry;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/cli",
3
- "version": "1.0.0-beta.129",
3
+ "version": "1.0.0-beta.130",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -33,23 +33,25 @@
33
33
  "Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)"
34
34
  ],
35
35
  "dependencies": {
36
- "@redocly/openapi-core": "1.0.0-beta.129",
36
+ "@redocly/openapi-core": "1.0.0-beta.130",
37
37
  "assert-node-version": "^1.0.3",
38
38
  "chokidar": "^3.5.1",
39
39
  "colorette": "^1.2.0",
40
40
  "glob": "^7.1.6",
41
41
  "glob-promise": "^3.4.0",
42
42
  "handlebars": "^4.7.6",
43
- "mobx": "^6.3.2",
44
43
  "portfinder": "^1.0.26",
45
- "react": "^17.0.1",
46
- "react-dom": "^17.0.1",
47
44
  "redoc": "~2.0.0",
48
45
  "semver": "^7.5.2",
49
46
  "simple-websocket": "^9.0.0",
50
- "styled-components": "5.3.3",
51
47
  "yargs": "17.0.1"
52
48
  },
49
+ "peerDependencies": {
50
+ "mobx": "^6.0.4",
51
+ "react": "^16.8.4 || ^17.0.0",
52
+ "react-dom": "^16.8.4 || ^17.0.0",
53
+ "styled-components": "^4.1.1 || ^5.1.1"
54
+ },
53
55
  "devDependencies": {
54
56
  "@types/configstore": "^5.0.1",
55
57
  "@types/react": "^17.0.8",