@redocly/cli 1.18.1 → 1.19.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 (91) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/lib/__mocks__/@redocly/openapi-core.d.ts +2 -2
  3. package/lib/__mocks__/@redocly/openapi-core.js +1 -0
  4. package/lib/__mocks__/fs.d.ts +0 -1
  5. package/lib/__mocks__/perf_hooks.d.ts +0 -1
  6. package/lib/__mocks__/redoc.d.ts +0 -1
  7. package/lib/__tests__/commands/build-docs.test.js +21 -23
  8. package/lib/__tests__/commands/bundle.test.js +21 -30
  9. package/lib/__tests__/commands/join.test.js +101 -70
  10. package/lib/__tests__/commands/lint.test.js +54 -54
  11. package/lib/__tests__/commands/push-region.test.js +24 -25
  12. package/lib/__tests__/commands/push.test.js +269 -170
  13. package/lib/__tests__/fetch-with-timeout.test.js +3 -12
  14. package/lib/__tests__/fixtures/config.d.ts +0 -1
  15. package/lib/__tests__/utils.test.js +32 -37
  16. package/lib/__tests__/wrapper.test.js +31 -20
  17. package/lib/cms/api/__tests__/api.client.test.js +29 -38
  18. package/lib/cms/api/api-client.d.ts +0 -2
  19. package/lib/cms/api/api-client.js +106 -127
  20. package/lib/cms/api/api-keys.js +1 -2
  21. package/lib/cms/api/domains.js +1 -2
  22. package/lib/cms/commands/__tests__/push-status.test.js +251 -162
  23. package/lib/cms/commands/__tests__/push.test.js +120 -102
  24. package/lib/cms/commands/__tests__/utils.test.js +12 -21
  25. package/lib/cms/commands/push-status.d.ts +3 -2
  26. package/lib/cms/commands/push-status.js +94 -106
  27. package/lib/cms/commands/push.d.ts +3 -2
  28. package/lib/cms/commands/push.js +66 -74
  29. package/lib/cms/commands/utils.js +20 -34
  30. package/lib/commands/build-docs/index.d.ts +2 -2
  31. package/lib/commands/build-docs/index.js +8 -17
  32. package/lib/commands/build-docs/utils.js +26 -38
  33. package/lib/commands/bundle.d.ts +2 -2
  34. package/lib/commands/bundle.js +70 -94
  35. package/lib/commands/join.d.ts +2 -2
  36. package/lib/commands/join.js +375 -388
  37. package/lib/commands/lint.d.ts +2 -2
  38. package/lib/commands/lint.js +64 -75
  39. package/lib/commands/login.d.ts +3 -2
  40. package/lib/commands/login.js +9 -21
  41. package/lib/commands/preview-docs/index.d.ts +2 -2
  42. package/lib/commands/preview-docs/index.js +92 -106
  43. package/lib/commands/preview-docs/preview-server/preview-server.js +64 -76
  44. package/lib/commands/preview-docs/preview-server/server.d.ts +0 -3
  45. package/lib/commands/preview-docs/preview-server/server.js +6 -6
  46. package/lib/commands/preview-project/index.d.ts +2 -1
  47. package/lib/commands/preview-project/index.js +5 -14
  48. package/lib/commands/push.d.ts +8 -11
  49. package/lib/commands/push.js +177 -195
  50. package/lib/commands/split/__tests__/index.test.js +31 -25
  51. package/lib/commands/split/index.d.ts +2 -1
  52. package/lib/commands/split/index.js +20 -33
  53. package/lib/commands/stats.d.ts +2 -2
  54. package/lib/commands/stats.js +34 -45
  55. package/lib/index.js +32 -46
  56. package/lib/types.d.ts +2 -2
  57. package/lib/utils/__mocks__/miscellaneous.d.ts +0 -1
  58. package/lib/utils/fetch-with-timeout.js +7 -12
  59. package/lib/utils/getCommandNameFromArgs.js +2 -4
  60. package/lib/utils/js-utils.js +6 -7
  61. package/lib/utils/miscellaneous.d.ts +4 -1
  62. package/lib/utils/miscellaneous.js +130 -152
  63. package/lib/utils/update-version-notifier.js +4 -13
  64. package/lib/wrapper.d.ts +9 -2
  65. package/lib/wrapper.js +27 -16
  66. package/package.json +3 -3
  67. package/src/__mocks__/@redocly/openapi-core.ts +1 -0
  68. package/src/__tests__/commands/build-docs.test.ts +5 -4
  69. package/src/__tests__/commands/join.test.ts +51 -51
  70. package/src/__tests__/commands/push-region.test.ts +10 -8
  71. package/src/__tests__/commands/push.test.ts +127 -102
  72. package/src/__tests__/utils.test.ts +1 -0
  73. package/src/__tests__/wrapper.test.ts +24 -2
  74. package/src/cms/commands/__tests__/push-status.test.ts +70 -56
  75. package/src/cms/commands/__tests__/push.test.ts +30 -24
  76. package/src/cms/commands/push-status.ts +8 -7
  77. package/src/cms/commands/push.ts +12 -9
  78. package/src/commands/build-docs/index.ts +10 -5
  79. package/src/commands/bundle.ts +14 -6
  80. package/src/commands/join.ts +6 -2
  81. package/src/commands/lint.ts +9 -3
  82. package/src/commands/login.ts +4 -2
  83. package/src/commands/preview-docs/index.ts +6 -1
  84. package/src/commands/preview-project/index.ts +5 -4
  85. package/src/commands/push.ts +13 -15
  86. package/src/commands/split/__tests__/index.test.ts +17 -6
  87. package/src/commands/split/index.ts +4 -2
  88. package/src/commands/stats.ts +4 -2
  89. package/src/utils/miscellaneous.ts +11 -1
  90. package/src/wrapper.ts +37 -11
  91. package/tsconfig.tsbuildinfo +1 -1
@@ -1,7 +1,7 @@
1
- import { Config } from '@redocly/openapi-core';
2
1
  import type { OutputFormat, RuleSeverity } from '@redocly/openapi-core';
3
2
  import type { RawConfigProcessor } from '@redocly/openapi-core/lib/config';
4
3
  import type { CommandOptions, Skips } from '../types';
4
+ import type { CommandArgs } from '../wrapper';
5
5
  export type LintOptions = {
6
6
  apis?: string[];
7
7
  'max-problems': number;
@@ -11,5 +11,5 @@ export type LintOptions = {
11
11
  'generate-ignore-file'?: boolean;
12
12
  'lint-config'?: RuleSeverity;
13
13
  } & Omit<Skips, 'skip-decorator'>;
14
- export declare function handleLint(argv: LintOptions, config: Config, version: string): Promise<void>;
14
+ export declare function handleLint({ argv, config, version, collectSpecData, }: CommandArgs<LintOptions>): Promise<void>;
15
15
  export declare function lintConfigCallback(argv: CommandOptions & Record<string, undefined>, version: string): RawConfigProcessor | undefined;
@@ -1,88 +1,78 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.lintConfigCallback = exports.handleLint = void 0;
3
+ exports.handleLint = handleLint;
4
+ exports.lintConfigCallback = lintConfigCallback;
13
5
  const colorette_1 = require("colorette");
14
6
  const perf_hooks_1 = require("perf_hooks");
15
7
  const openapi_core_1 = require("@redocly/openapi-core");
16
8
  const config_1 = require("@redocly/openapi-core/lib/config");
17
9
  const miscellaneous_1 = require("../utils/miscellaneous");
18
10
  const getCommandNameFromArgs_1 = require("../utils/getCommandNameFromArgs");
19
- function handleLint(argv, config, version) {
20
- return __awaiter(this, void 0, void 0, function* () {
21
- const apis = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.apis, config);
22
- if (!apis.length) {
23
- (0, miscellaneous_1.exitWithError)('No APIs were provided.');
24
- }
25
- if (argv['generate-ignore-file']) {
26
- config.styleguide.ignore = {}; // clear ignore
27
- }
28
- const totals = { errors: 0, warnings: 0, ignored: 0 };
29
- let totalIgnored = 0;
30
- // TODO: use shared externalRef resolver, blocked by preprocessors now as they can mutate documents
31
- for (const { path, alias } of apis) {
32
- try {
33
- const startedAt = perf_hooks_1.performance.now();
34
- const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, alias);
35
- const { styleguide } = resolvedConfig;
36
- (0, miscellaneous_1.checkIfRulesetExist)(styleguide.rules);
37
- styleguide.skipRules(argv['skip-rule']);
38
- styleguide.skipPreprocessors(argv['skip-preprocessor']);
39
- if (styleguide.recommendedFallback) {
40
- process.stderr.write(`No configurations were provided -- using built in ${(0, colorette_1.blue)('recommended')} configuration by default.\n\n`);
41
- }
42
- process.stderr.write((0, colorette_1.gray)(`validating ${path.replace(process.cwd(), '')}...\n`));
43
- const results = yield (0, openapi_core_1.lint)({
44
- ref: path,
45
- config: resolvedConfig,
46
- });
47
- const fileTotals = (0, openapi_core_1.getTotals)(results);
48
- totals.errors += fileTotals.errors;
49
- totals.warnings += fileTotals.warnings;
50
- totals.ignored += fileTotals.ignored;
51
- if (argv['generate-ignore-file']) {
52
- for (const m of results) {
53
- config.styleguide.addIgnore(m);
54
- totalIgnored++;
55
- }
56
- }
57
- else {
58
- (0, openapi_core_1.formatProblems)(results, {
59
- format: argv.format,
60
- maxProblems: argv['max-problems'],
61
- totals: fileTotals,
62
- version,
63
- });
11
+ async function handleLint({ argv, config, version, collectSpecData, }) {
12
+ const apis = await (0, miscellaneous_1.getFallbackApisOrExit)(argv.apis, config);
13
+ if (!apis.length) {
14
+ (0, miscellaneous_1.exitWithError)('No APIs were provided.');
15
+ }
16
+ if (argv['generate-ignore-file']) {
17
+ config.styleguide.ignore = {}; // clear ignore
18
+ }
19
+ const totals = { errors: 0, warnings: 0, ignored: 0 };
20
+ let totalIgnored = 0;
21
+ // TODO: use shared externalRef resolver, blocked by preprocessors now as they can mutate documents
22
+ for (const { path, alias } of apis) {
23
+ try {
24
+ const startedAt = perf_hooks_1.performance.now();
25
+ const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, alias);
26
+ const { styleguide } = resolvedConfig;
27
+ (0, miscellaneous_1.checkIfRulesetExist)(styleguide.rules);
28
+ styleguide.skipRules(argv['skip-rule']);
29
+ styleguide.skipPreprocessors(argv['skip-preprocessor']);
30
+ if (styleguide.recommendedFallback) {
31
+ process.stderr.write(`No configurations were provided -- using built in ${(0, colorette_1.blue)('recommended')} configuration by default.\n\n`);
32
+ }
33
+ process.stderr.write((0, colorette_1.gray)(`validating ${path.replace(process.cwd(), '')}...\n`));
34
+ const results = await (0, openapi_core_1.lint)({
35
+ ref: path,
36
+ config: resolvedConfig,
37
+ collectSpecData,
38
+ });
39
+ const fileTotals = (0, openapi_core_1.getTotals)(results);
40
+ totals.errors += fileTotals.errors;
41
+ totals.warnings += fileTotals.warnings;
42
+ totals.ignored += fileTotals.ignored;
43
+ if (argv['generate-ignore-file']) {
44
+ for (const m of results) {
45
+ config.styleguide.addIgnore(m);
46
+ totalIgnored++;
64
47
  }
65
- const elapsed = (0, miscellaneous_1.getExecutionTime)(startedAt);
66
- process.stderr.write((0, colorette_1.gray)(`${path.replace(process.cwd(), '')}: validated in ${elapsed}\n\n`));
67
48
  }
68
- catch (e) {
69
- (0, miscellaneous_1.handleError)(e, path);
49
+ else {
50
+ (0, openapi_core_1.formatProblems)(results, {
51
+ format: argv.format,
52
+ maxProblems: argv['max-problems'],
53
+ totals: fileTotals,
54
+ version,
55
+ });
70
56
  }
57
+ const elapsed = (0, miscellaneous_1.getExecutionTime)(startedAt);
58
+ process.stderr.write((0, colorette_1.gray)(`${path.replace(process.cwd(), '')}: validated in ${elapsed}\n\n`));
71
59
  }
72
- if (argv['generate-ignore-file']) {
73
- config.styleguide.saveIgnore();
74
- process.stderr.write(`Generated ignore file with ${totalIgnored} ${(0, miscellaneous_1.pluralize)('problem', totalIgnored)}.\n\n`);
75
- }
76
- else {
77
- (0, miscellaneous_1.printLintTotals)(totals, apis.length);
78
- }
79
- (0, miscellaneous_1.printUnusedWarnings)(config.styleguide);
80
- if (!(totals.errors === 0 || argv['generate-ignore-file'])) {
81
- throw new Error('Lint failed.');
60
+ catch (e) {
61
+ (0, miscellaneous_1.handleError)(e, path);
82
62
  }
83
- });
63
+ }
64
+ if (argv['generate-ignore-file']) {
65
+ config.styleguide.saveIgnore();
66
+ process.stderr.write(`Generated ignore file with ${totalIgnored} ${(0, miscellaneous_1.pluralize)('problem', totalIgnored)}.\n\n`);
67
+ }
68
+ else {
69
+ (0, miscellaneous_1.printLintTotals)(totals, apis.length);
70
+ }
71
+ (0, miscellaneous_1.printUnusedWarnings)(config.styleguide);
72
+ if (!(totals.errors === 0 || argv['generate-ignore-file'])) {
73
+ throw new Error('Lint failed.');
74
+ }
84
75
  }
85
- exports.handleLint = handleLint;
86
76
  function lintConfigCallback(argv, version) {
87
77
  if (argv['lint-config'] === 'off') {
88
78
  return;
@@ -91,12 +81,12 @@ function lintConfigCallback(argv, version) {
91
81
  // we can't print config lint results as it will break json output
92
82
  return;
93
83
  }
94
- return ({ document, resolvedRefMap, config, parsed: { theme = {} } }) => __awaiter(this, void 0, void 0, function* () {
84
+ return async ({ document, resolvedRefMap, config, parsed: { theme = {} } }) => {
95
85
  const command = argv ? (0, getCommandNameFromArgs_1.getCommandNameFromArgs)(argv) : undefined;
96
86
  if (command === 'check-config') {
97
87
  (0, miscellaneous_1.notifyAboutIncompatibleConfigOptions)(theme.openapi);
98
88
  }
99
- const problems = yield (0, openapi_core_1.lintConfig)({
89
+ const problems = await (0, openapi_core_1.lintConfig)({
100
90
  document,
101
91
  resolvedRefMap,
102
92
  config,
@@ -113,6 +103,5 @@ function lintConfigCallback(argv, version) {
113
103
  if (fileTotals.errors > 0) {
114
104
  throw new config_1.ConfigValidationError();
115
105
  }
116
- });
106
+ };
117
107
  }
118
- exports.lintConfigCallback = lintConfigCallback;
@@ -1,8 +1,9 @@
1
- import { Region, Config } from '@redocly/openapi-core';
1
+ import { Region } from '@redocly/openapi-core';
2
+ import type { CommandArgs } from '../wrapper';
2
3
  export declare function promptClientToken(domain: string): Promise<string>;
3
4
  export type LoginOptions = {
4
5
  verbose?: boolean;
5
6
  region?: Region;
6
7
  config?: string;
7
8
  };
8
- export declare function handleLogin(argv: LoginOptions, config: Config): Promise<void>;
9
+ export declare function handleLogin({ argv, config }: CommandArgs<LoginOptions>): Promise<void>;
@@ -1,30 +1,18 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.handleLogin = exports.promptClientToken = void 0;
3
+ exports.promptClientToken = promptClientToken;
4
+ exports.handleLogin = handleLogin;
13
5
  const openapi_core_1 = require("@redocly/openapi-core");
14
6
  const colorette_1 = require("colorette");
15
7
  const miscellaneous_1 = require("../utils/miscellaneous");
16
8
  function promptClientToken(domain) {
17
9
  return (0, miscellaneous_1.promptUser)((0, colorette_1.green)(`\n 🔑 Copy your API key from ${(0, colorette_1.blue)(`https://app.${domain}/profile`)} and paste it below`), true);
18
10
  }
19
- exports.promptClientToken = promptClientToken;
20
- function handleLogin(argv, config) {
21
- return __awaiter(this, void 0, void 0, function* () {
22
- const region = argv.region || config.region;
23
- const client = new openapi_core_1.RedoclyClient(region);
24
- const clientToken = yield promptClientToken(client.domain);
25
- process.stdout.write((0, colorette_1.gray)('\n Logging in...\n'));
26
- yield client.login(clientToken, argv.verbose);
27
- process.stdout.write((0, colorette_1.green)(' Authorization confirmed. ✅\n\n'));
28
- });
11
+ async function handleLogin({ argv, config }) {
12
+ const region = argv.region || config.region;
13
+ const client = new openapi_core_1.RedoclyClient(region);
14
+ const clientToken = await promptClientToken(client.domain);
15
+ process.stdout.write((0, colorette_1.gray)('\n Logging in...\n'));
16
+ await client.login(clientToken, argv.verbose);
17
+ process.stdout.write((0, colorette_1.green)(' Authorization confirmed. ✅\n\n'));
29
18
  }
30
- exports.handleLogin = handleLogin;
@@ -1,5 +1,5 @@
1
- import { Config } from '@redocly/openapi-core';
2
1
  import type { Skips } from '../../types';
2
+ import type { CommandArgs } from '../../wrapper';
3
3
  export type PreviewDocsOptions = {
4
4
  port: number;
5
5
  host: string;
@@ -8,5 +8,5 @@ export type PreviewDocsOptions = {
8
8
  api?: string;
9
9
  force?: boolean;
10
10
  } & Omit<Skips, 'skip-rule'>;
11
- export declare function previewDocs(argv: PreviewDocsOptions, configFromFile: Config): Promise<void>;
11
+ export declare function previewDocs({ argv, config: configFromFile, }: CommandArgs<PreviewDocsOptions>): Promise<void>;
12
12
  export declare function debounce(func: Function, wait: number, immediate?: boolean): (...args: any[]) => void;
@@ -1,122 +1,109 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.debounce = exports.previewDocs = void 0;
3
+ exports.previewDocs = previewDocs;
4
+ exports.debounce = debounce;
13
5
  const colorette = require("colorette");
14
6
  const chockidar = require("chokidar");
15
7
  const openapi_core_1 = require("@redocly/openapi-core");
16
8
  const miscellaneous_1 = require("../../utils/miscellaneous");
17
9
  const preview_server_1 = require("./preview-server/preview-server");
18
- function previewDocs(argv, configFromFile) {
19
- return __awaiter(this, void 0, void 0, function* () {
20
- let isAuthorizedWithRedocly = false;
21
- let redocOptions = {};
22
- let config = yield reloadConfig(configFromFile);
23
- const apis = yield (0, miscellaneous_1.getFallbackApisOrExit)(argv.api ? [argv.api] : [], config);
24
- const api = apis[0];
25
- let cachedBundle;
26
- const deps = new Set();
27
- function getBundle() {
28
- return __awaiter(this, void 0, void 0, function* () {
29
- return cachedBundle;
10
+ async function previewDocs({ argv, config: configFromFile, }) {
11
+ let isAuthorizedWithRedocly = false;
12
+ let redocOptions = {};
13
+ let config = await reloadConfig(configFromFile);
14
+ const apis = await (0, miscellaneous_1.getFallbackApisOrExit)(argv.api ? [argv.api] : [], config);
15
+ const api = apis[0];
16
+ let cachedBundle;
17
+ const deps = new Set();
18
+ async function getBundle() {
19
+ return cachedBundle;
20
+ }
21
+ async function updateBundle() {
22
+ process.stdout.write('\nBundling...\n\n');
23
+ try {
24
+ const { bundle: openapiBundle, problems, fileDependencies, } = await (0, openapi_core_1.bundle)({
25
+ ref: api.path,
26
+ config,
30
27
  });
28
+ const removed = [...deps].filter((x) => !fileDependencies.has(x));
29
+ watcher.unwatch(removed);
30
+ watcher.add([...fileDependencies]);
31
+ deps.clear();
32
+ fileDependencies.forEach(deps.add, deps);
33
+ const fileTotals = (0, openapi_core_1.getTotals)(problems);
34
+ if (fileTotals.errors === 0) {
35
+ process.stdout.write(fileTotals.errors === 0
36
+ ? `Created a bundle for ${api.alias || api.path} ${fileTotals.warnings > 0 ? 'with warnings' : 'successfully'}\n`
37
+ : colorette.yellow(`Created a bundle for ${api.alias || api.path} with errors. Docs may be broken or not accurate\n`));
38
+ }
39
+ return openapiBundle.parsed;
31
40
  }
32
- function updateBundle() {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- process.stdout.write('\nBundling...\n\n');
35
- try {
36
- const { bundle: openapiBundle, problems, fileDependencies, } = yield (0, openapi_core_1.bundle)({
37
- ref: api.path,
38
- config,
39
- });
40
- const removed = [...deps].filter((x) => !fileDependencies.has(x));
41
- watcher.unwatch(removed);
42
- watcher.add([...fileDependencies]);
43
- deps.clear();
44
- fileDependencies.forEach(deps.add, deps);
45
- const fileTotals = (0, openapi_core_1.getTotals)(problems);
46
- if (fileTotals.errors === 0) {
47
- process.stdout.write(fileTotals.errors === 0
48
- ? `Created a bundle for ${api.alias || api.path} ${fileTotals.warnings > 0 ? 'with warnings' : 'successfully'}\n`
49
- : colorette.yellow(`Created a bundle for ${api.alias || api.path} with errors. Docs may be broken or not accurate\n`));
50
- }
51
- return openapiBundle.parsed;
52
- }
53
- catch (e) {
54
- (0, miscellaneous_1.handleError)(e, api.path);
55
- }
56
- });
41
+ catch (e) {
42
+ (0, miscellaneous_1.handleError)(e, api.path);
57
43
  }
58
- setImmediate(() => {
59
- cachedBundle = updateBundle();
60
- }); // initial cache
61
- const isAuthorized = isAuthorizedWithRedocly || redocOptions.licenseKey;
62
- if (!isAuthorized) {
63
- process.stderr.write(`Using Redoc community edition.\nLogin with redocly ${colorette.blue('login')} or use an enterprise license key to preview with the premium docs.\n\n`);
44
+ }
45
+ setImmediate(() => {
46
+ cachedBundle = updateBundle();
47
+ }); // initial cache
48
+ const isAuthorized = isAuthorizedWithRedocly || redocOptions.licenseKey;
49
+ if (!isAuthorized) {
50
+ process.stderr.write(`Using Redoc community edition.\nLogin with redocly ${colorette.blue('login')} or use an enterprise license key to preview with the premium docs.\n\n`);
51
+ }
52
+ const hotClients = await (0, preview_server_1.default)(argv.port, argv.host, {
53
+ getBundle,
54
+ getOptions: () => redocOptions,
55
+ useRedocPro: isAuthorized && !redocOptions.useCommunityEdition,
56
+ });
57
+ const watchPaths = [api.path, config.configFile].filter((e) => !!e);
58
+ const watcher = chockidar.watch(watchPaths, {
59
+ disableGlobbing: true,
60
+ ignoreInitial: true,
61
+ });
62
+ const debouncedUpdatedBundle = debounce(async () => {
63
+ cachedBundle = updateBundle();
64
+ await cachedBundle;
65
+ hotClients.broadcast('{"type": "reload", "bundle": true}');
66
+ }, 2000);
67
+ const changeHandler = async (type, file) => {
68
+ process.stdout.write(`${colorette.green('watch')} ${type} ${colorette.blue(file)}\n`);
69
+ if (file === config.configFile) {
70
+ config = await reloadConfig();
71
+ hotClients.broadcast(JSON.stringify({ type: 'reload' }));
72
+ return;
64
73
  }
65
- const hotClients = yield (0, preview_server_1.default)(argv.port, argv.host, {
66
- getBundle,
67
- getOptions: () => redocOptions,
68
- useRedocPro: isAuthorized && !redocOptions.useCommunityEdition,
69
- });
70
- const watchPaths = [api.path, config.configFile].filter((e) => !!e);
71
- const watcher = chockidar.watch(watchPaths, {
72
- disableGlobbing: true,
73
- ignoreInitial: true,
74
- });
75
- const debouncedUpdatedBundle = debounce(() => __awaiter(this, void 0, void 0, function* () {
76
- cachedBundle = updateBundle();
77
- yield cachedBundle;
78
- hotClients.broadcast('{"type": "reload", "bundle": true}');
79
- }), 2000);
80
- const changeHandler = (type, file) => __awaiter(this, void 0, void 0, function* () {
81
- process.stdout.write(`${colorette.green('watch')} ${type} ${colorette.blue(file)}\n`);
82
- if (file === config.configFile) {
83
- config = yield reloadConfig();
84
- hotClients.broadcast(JSON.stringify({ type: 'reload' }));
85
- return;
74
+ debouncedUpdatedBundle();
75
+ };
76
+ watcher.on('change', changeHandler.bind(undefined, 'changed'));
77
+ watcher.on('add', changeHandler.bind(undefined, 'added'));
78
+ watcher.on('unlink', changeHandler.bind(undefined, 'removed'));
79
+ watcher.on('ready', () => {
80
+ process.stdout.write(`\n 👀 Watching ${colorette.blue(api.path)} and all related resources for changes\n\n`);
81
+ });
82
+ async function reloadConfig(config) {
83
+ if (!config) {
84
+ try {
85
+ config = (await (0, miscellaneous_1.loadConfigAndHandleErrors)({ configPath: argv.config }));
86
+ }
87
+ catch (err) {
88
+ config = new openapi_core_1.Config({ apis: {}, styleguide: {} });
86
89
  }
87
- debouncedUpdatedBundle();
88
- });
89
- watcher.on('change', changeHandler.bind(undefined, 'changed'));
90
- watcher.on('add', changeHandler.bind(undefined, 'added'));
91
- watcher.on('unlink', changeHandler.bind(undefined, 'removed'));
92
- watcher.on('ready', () => {
93
- process.stdout.write(`\n 👀 Watching ${colorette.blue(api.path)} and all related resources for changes\n\n`);
94
- });
95
- function reloadConfig(config) {
96
- var _a;
97
- return __awaiter(this, void 0, void 0, function* () {
98
- if (!config) {
99
- try {
100
- config = (yield (0, miscellaneous_1.loadConfigAndHandleErrors)({ configPath: argv.config }));
101
- }
102
- catch (err) {
103
- config = new openapi_core_1.Config({ apis: {}, styleguide: {} });
104
- }
105
- }
106
- const redoclyClient = new openapi_core_1.RedoclyClient();
107
- isAuthorizedWithRedocly = yield redoclyClient.isAuthorizedWithRedocly();
108
- const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, argv.api);
109
- const { styleguide } = resolvedConfig;
110
- styleguide.skipPreprocessors(argv['skip-preprocessor']);
111
- styleguide.skipDecorators(argv['skip-decorator']);
112
- const referenceDocs = (_a = resolvedConfig.theme) === null || _a === void 0 ? void 0 : _a.openapi;
113
- redocOptions = Object.assign(Object.assign({}, referenceDocs), { useCommunityEdition: argv['use-community-edition'] || (referenceDocs === null || referenceDocs === void 0 ? void 0 : referenceDocs.useCommunityEdition), licenseKey: process.env.REDOCLY_LICENSE_KEY || (referenceDocs === null || referenceDocs === void 0 ? void 0 : referenceDocs.licenseKey), whiteLabel: true });
114
- return resolvedConfig;
115
- });
116
90
  }
117
- });
91
+ const redoclyClient = new openapi_core_1.RedoclyClient();
92
+ isAuthorizedWithRedocly = await redoclyClient.isAuthorizedWithRedocly();
93
+ const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, argv.api);
94
+ const { styleguide } = resolvedConfig;
95
+ styleguide.skipPreprocessors(argv['skip-preprocessor']);
96
+ styleguide.skipDecorators(argv['skip-decorator']);
97
+ const referenceDocs = resolvedConfig.theme?.openapi;
98
+ redocOptions = {
99
+ ...referenceDocs,
100
+ useCommunityEdition: argv['use-community-edition'] || referenceDocs?.useCommunityEdition,
101
+ licenseKey: process.env.REDOCLY_LICENSE_KEY || referenceDocs?.licenseKey,
102
+ whiteLabel: true,
103
+ };
104
+ return resolvedConfig;
105
+ }
118
106
  }
119
- exports.previewDocs = previewDocs;
120
107
  function debounce(func, wait, immediate) {
121
108
  let timeout;
122
109
  return function executedFunction(...args) {
@@ -137,4 +124,3 @@ function debounce(func, wait, immediate) {
137
124
  func.apply(context, args);
138
125
  };
139
126
  }
140
- exports.debounce = debounce;
@@ -1,14 +1,6 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = startPreviewServer;
12
4
  const handlebars_1 = require("handlebars");
13
5
  const colorette = require("colorette");
14
6
  const get_port_please_1 = require("get-port-please");
@@ -47,79 +39,75 @@ function getPageHTML(htmlTemplate, redocOptions = {}, useRedocPro, wsPort, host)
47
39
  </script>`,
48
40
  });
49
41
  }
50
- function startPreviewServer(port, host, { getBundle, getOptions, useRedocPro, }) {
51
- return __awaiter(this, void 0, void 0, function* () {
52
- const defaultTemplate = path.join(__dirname, 'default.hbs');
53
- const handler = (request, response) => __awaiter(this, void 0, void 0, function* () {
54
- var _a;
55
- console.time(colorette.dim(`GET ${request.url}`));
56
- const { htmlTemplate } = getOptions() || {};
57
- if (((_a = request.url) === null || _a === void 0 ? void 0 : _a.endsWith('/')) || path.extname(request.url) === '') {
58
- (0, server_1.respondWithGzip)(getPageHTML(htmlTemplate || defaultTemplate, getOptions(), useRedocPro, wsPort, host), request, response, {
59
- 'Content-Type': 'text/html',
42
+ async function startPreviewServer(port, host, { getBundle, getOptions, useRedocPro, }) {
43
+ const defaultTemplate = path.join(__dirname, 'default.hbs');
44
+ const handler = async (request, response) => {
45
+ console.time(colorette.dim(`GET ${request.url}`));
46
+ const { htmlTemplate } = getOptions() || {};
47
+ if (request.url?.endsWith('/') || path.extname(request.url) === '') {
48
+ (0, server_1.respondWithGzip)(getPageHTML(htmlTemplate || defaultTemplate, getOptions(), useRedocPro, wsPort, host), request, response, {
49
+ 'Content-Type': 'text/html',
50
+ });
51
+ }
52
+ else if (request.url === '/openapi.json') {
53
+ const bundle = await getBundle();
54
+ if (bundle === undefined) {
55
+ (0, server_1.respondWithGzip)(JSON.stringify({
56
+ openapi: '3.0.0',
57
+ info: {
58
+ description: '<code> Failed to generate bundle: check out console output for more details </code>',
59
+ },
60
+ paths: {},
61
+ }), request, response, {
62
+ 'Content-Type': 'application/json',
60
63
  });
61
64
  }
62
- else if (request.url === '/openapi.json') {
63
- const bundle = yield getBundle();
64
- if (bundle === undefined) {
65
- (0, server_1.respondWithGzip)(JSON.stringify({
66
- openapi: '3.0.0',
67
- info: {
68
- description: '<code> Failed to generate bundle: check out console output for more details </code>',
69
- },
70
- paths: {},
71
- }), request, response, {
72
- 'Content-Type': 'application/json',
73
- });
74
- }
75
- else {
76
- (0, server_1.respondWithGzip)(JSON.stringify(bundle), request, response, {
77
- 'Content-Type': 'application/json',
78
- });
79
- }
80
- }
81
65
  else {
82
- let filePath =
83
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
84
- // @ts-ignore
85
- {
86
- '/hot.js': path.join(__dirname, 'hot.js'),
87
- '/oauth2-redirect.html': path.join(__dirname, 'oauth2-redirect.html'),
88
- '/simplewebsocket.min.js': require.resolve('simple-websocket/simplewebsocket.min.js'),
89
- }[request.url || ''];
90
- if (!filePath) {
91
- const basePath = htmlTemplate ? path.dirname(htmlTemplate) : process.cwd();
92
- filePath = path.resolve(basePath, `.${request.url}`);
93
- if (!(0, miscellaneous_1.isSubdir)(basePath, filePath)) {
94
- (0, server_1.respondWithGzip)('404 Not Found', request, response, { 'Content-Type': 'text/html' }, 404);
95
- console.timeEnd(colorette.dim(`GET ${request.url}`));
96
- return;
97
- }
66
+ (0, server_1.respondWithGzip)(JSON.stringify(bundle), request, response, {
67
+ 'Content-Type': 'application/json',
68
+ });
69
+ }
70
+ }
71
+ else {
72
+ let filePath =
73
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
74
+ // @ts-ignore
75
+ {
76
+ '/hot.js': path.join(__dirname, 'hot.js'),
77
+ '/oauth2-redirect.html': path.join(__dirname, 'oauth2-redirect.html'),
78
+ '/simplewebsocket.min.js': require.resolve('simple-websocket/simplewebsocket.min.js'),
79
+ }[request.url || ''];
80
+ if (!filePath) {
81
+ const basePath = htmlTemplate ? path.dirname(htmlTemplate) : process.cwd();
82
+ filePath = path.resolve(basePath, `.${request.url}`);
83
+ if (!(0, miscellaneous_1.isSubdir)(basePath, filePath)) {
84
+ (0, server_1.respondWithGzip)('404 Not Found', request, response, { 'Content-Type': 'text/html' }, 404);
85
+ console.timeEnd(colorette.dim(`GET ${request.url}`));
86
+ return;
98
87
  }
99
- const extname = String(path.extname(filePath)).toLowerCase();
100
- const contentType = server_1.mimeTypes[extname] || 'application/octet-stream';
101
- try {
102
- (0, server_1.respondWithGzip)(yield fs_1.promises.readFile(filePath), request, response, {
103
- 'Content-Type': contentType,
104
- });
88
+ }
89
+ const extname = String(path.extname(filePath)).toLowerCase();
90
+ const contentType = server_1.mimeTypes[extname] || 'application/octet-stream';
91
+ try {
92
+ (0, server_1.respondWithGzip)(await fs_1.promises.readFile(filePath), request, response, {
93
+ 'Content-Type': contentType,
94
+ });
95
+ }
96
+ catch (e) {
97
+ if (e.code === 'ENOENT') {
98
+ (0, server_1.respondWithGzip)('404 Not Found', request, response, { 'Content-Type': 'text/html' }, 404);
105
99
  }
106
- catch (e) {
107
- if (e.code === 'ENOENT') {
108
- (0, server_1.respondWithGzip)('404 Not Found', request, response, { 'Content-Type': 'text/html' }, 404);
109
- }
110
- else {
111
- (0, server_1.respondWithGzip)(`Something went wrong: ${e.code || e.message}...\n`, request, response, {}, 500);
112
- }
100
+ else {
101
+ (0, server_1.respondWithGzip)(`Something went wrong: ${e.code || e.message}...\n`, request, response, {}, 500);
113
102
  }
114
103
  }
115
- console.timeEnd(colorette.dim(`GET ${request.url}`));
116
- });
117
- const wsPort = yield (0, get_port_please_1.getPort)({ port: 32201, portRange: [32201, 32301], host });
118
- const server = (0, server_1.startHttpServer)(port, host, handler);
119
- server.on('listening', () => {
120
- process.stdout.write(`\n 🔎 Preview server running at ${colorette.blue(`http://${host}:${port}\n`)}`);
121
- });
122
- return (0, server_1.startWsServer)(wsPort, host);
104
+ }
105
+ console.timeEnd(colorette.dim(`GET ${request.url}`));
106
+ };
107
+ const wsPort = await (0, get_port_please_1.getPort)({ port: 32201, portRange: [32201, 32301], host });
108
+ const server = (0, server_1.startHttpServer)(port, host, handler);
109
+ server.on('listening', () => {
110
+ process.stdout.write(`\n 🔎 Preview server running at ${colorette.blue(`http://${host}:${port}\n`)}`);
123
111
  });
112
+ return (0, server_1.startWsServer)(wsPort, host);
124
113
  }
125
- exports.default = startPreviewServer;