@redocly/cli 1.34.3 → 2.0.0-next.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 (321) hide show
  1. package/README.md +34 -3
  2. package/bin/cli.js +1 -1
  3. package/lib/auth/device-flow.d.ts +1 -0
  4. package/lib/auth/device-flow.d.ts.map +1 -0
  5. package/lib/auth/device-flow.js +15 -17
  6. package/lib/auth/device-flow.js.map +1 -0
  7. package/lib/auth/oauth-client.d.ts +1 -0
  8. package/lib/auth/oauth-client.d.ts.map +1 -0
  9. package/lib/auth/oauth-client.js +21 -23
  10. package/lib/auth/oauth-client.js.map +1 -0
  11. package/lib/commands/auth.d.ts +3 -5
  12. package/lib/commands/auth.d.ts.map +1 -0
  13. package/lib/commands/auth.js +19 -44
  14. package/lib/commands/auth.js.map +1 -0
  15. package/lib/commands/build-docs/index.d.ts +4 -3
  16. package/lib/commands/build-docs/index.d.ts.map +1 -0
  17. package/lib/commands/build-docs/index.js +23 -24
  18. package/lib/commands/build-docs/index.js.map +1 -0
  19. package/lib/commands/build-docs/types.d.ts +2 -1
  20. package/lib/commands/build-docs/types.d.ts.map +1 -0
  21. package/lib/commands/build-docs/types.js +2 -2
  22. package/lib/commands/build-docs/types.js.map +1 -0
  23. package/lib/commands/build-docs/utils.d.ts +3 -2
  24. package/lib/commands/build-docs/utils.d.ts.map +1 -0
  25. package/lib/commands/build-docs/utils.js +35 -37
  26. package/lib/commands/build-docs/utils.js.map +1 -0
  27. package/lib/commands/bundle.d.ts +6 -3
  28. package/lib/commands/bundle.d.ts.map +1 -0
  29. package/lib/commands/bundle.js +34 -38
  30. package/lib/commands/bundle.js.map +1 -0
  31. package/lib/commands/eject.d.ts +3 -2
  32. package/lib/commands/eject.d.ts.map +1 -0
  33. package/lib/commands/eject.js +11 -13
  34. package/lib/commands/eject.js.map +1 -0
  35. package/lib/commands/join.d.ts +4 -3
  36. package/lib/commands/join.d.ts.map +1 -0
  37. package/lib/commands/join.js +79 -81
  38. package/lib/commands/join.js.map +1 -0
  39. package/lib/commands/lint.d.ts +8 -6
  40. package/lib/commands/lint.d.ts.map +1 -0
  41. package/lib/commands/lint.js +53 -62
  42. package/lib/commands/lint.js.map +1 -0
  43. package/lib/commands/preview-project/constants.d.ts +2 -1
  44. package/lib/commands/preview-project/constants.d.ts.map +1 -0
  45. package/lib/commands/preview-project/constants.js +4 -6
  46. package/lib/commands/preview-project/constants.js.map +1 -0
  47. package/lib/commands/preview-project/index.d.ts +3 -2
  48. package/lib/commands/preview-project/index.d.ts.map +1 -0
  49. package/lib/commands/preview-project/index.js +21 -23
  50. package/lib/commands/preview-project/index.js.map +1 -0
  51. package/lib/commands/preview-project/types.d.ts +3 -2
  52. package/lib/commands/preview-project/types.d.ts.map +1 -0
  53. package/lib/commands/preview-project/types.js +2 -2
  54. package/lib/commands/preview-project/types.js.map +1 -0
  55. package/lib/commands/split/index.d.ts +4 -3
  56. package/lib/commands/split/index.d.ts.map +1 -0
  57. package/lib/commands/split/index.js +53 -57
  58. package/lib/commands/split/index.js.map +1 -0
  59. package/lib/commands/split/types.d.ts +2 -2
  60. package/lib/commands/split/types.d.ts.map +1 -0
  61. package/lib/commands/split/types.js +11 -13
  62. package/lib/commands/split/types.js.map +1 -0
  63. package/lib/commands/stats.d.ts +3 -2
  64. package/lib/commands/stats.d.ts.map +1 -0
  65. package/lib/commands/stats.js +21 -24
  66. package/lib/commands/stats.js.map +1 -0
  67. package/lib/commands/translations.d.ts +3 -2
  68. package/lib/commands/translations.d.ts.map +1 -0
  69. package/lib/commands/translations.js +11 -13
  70. package/lib/commands/translations.js.map +1 -0
  71. package/lib/index.d.ts +2 -1
  72. package/lib/index.d.ts.map +1 -0
  73. package/lib/index.js +109 -239
  74. package/lib/index.js.map +1 -0
  75. package/lib/otel.d.ts +2 -1
  76. package/lib/otel.d.ts.map +1 -0
  77. package/lib/otel.js +22 -23
  78. package/lib/otel.js.map +1 -0
  79. package/lib/reunite/api/api-client.d.ts +4 -3
  80. package/lib/reunite/api/api-client.d.ts.map +1 -0
  81. package/lib/reunite/api/api-client.js +14 -20
  82. package/lib/reunite/api/api-client.js.map +1 -0
  83. package/lib/reunite/api/api-keys.d.ts +2 -1
  84. package/lib/reunite/api/api-keys.d.ts.map +1 -0
  85. package/lib/reunite/api/api-keys.js +4 -20
  86. package/lib/reunite/api/api-keys.js.map +1 -0
  87. package/lib/reunite/api/domains.d.ts +5 -2
  88. package/lib/reunite/api/domains.d.ts.map +1 -0
  89. package/lib/reunite/api/domains.js +6 -15
  90. package/lib/reunite/api/domains.js.map +1 -0
  91. package/lib/reunite/api/index.d.ts +4 -3
  92. package/lib/reunite/api/index.d.ts.map +1 -0
  93. package/lib/reunite/api/index.js +4 -19
  94. package/lib/reunite/api/index.js.map +1 -0
  95. package/lib/reunite/api/types.d.ts +1 -0
  96. package/lib/reunite/api/types.d.ts.map +1 -0
  97. package/lib/reunite/api/types.js +2 -2
  98. package/lib/reunite/api/types.js.map +1 -0
  99. package/lib/reunite/commands/push-status.d.ts +6 -5
  100. package/lib/reunite/commands/push-status.d.ts.map +1 -0
  101. package/lib/reunite/commands/push-status.js +31 -37
  102. package/lib/reunite/commands/push-status.js.map +1 -0
  103. package/lib/reunite/commands/push.d.ts +6 -6
  104. package/lib/reunite/commands/push.d.ts.map +1 -0
  105. package/lib/reunite/commands/push.js +31 -40
  106. package/lib/reunite/commands/push.js.map +1 -0
  107. package/lib/reunite/commands/utils.d.ts +4 -3
  108. package/lib/reunite/commands/utils.d.ts.map +1 -0
  109. package/lib/reunite/commands/utils.js +9 -12
  110. package/lib/reunite/commands/utils.js.map +1 -0
  111. package/lib/reunite/utils.d.ts +1 -0
  112. package/lib/reunite/utils.d.ts.map +1 -0
  113. package/lib/reunite/utils.js +2 -5
  114. package/lib/reunite/utils.js.map +1 -0
  115. package/lib/types.d.ts +15 -27
  116. package/lib/types.d.ts.map +1 -0
  117. package/lib/types.js +2 -5
  118. package/lib/types.js.map +1 -0
  119. package/lib/utils/assert-node-version.d.ts +1 -0
  120. package/lib/utils/assert-node-version.d.ts.map +1 -0
  121. package/lib/utils/assert-node-version.js +8 -10
  122. package/lib/utils/assert-node-version.js.map +1 -0
  123. package/lib/utils/error.d.ts +4 -0
  124. package/lib/utils/error.d.ts.map +1 -0
  125. package/lib/utils/error.js +8 -0
  126. package/lib/utils/error.js.map +1 -0
  127. package/lib/utils/fetch-with-timeout.d.ts +1 -0
  128. package/lib/utils/fetch-with-timeout.d.ts.map +1 -0
  129. package/lib/utils/fetch-with-timeout.js +6 -8
  130. package/lib/utils/fetch-with-timeout.js.map +1 -0
  131. package/lib/utils/{getCommandNameFromArgs.d.ts → get-command-name-from-args.d.ts} +1 -0
  132. package/lib/utils/get-command-name-from-args.d.ts.map +1 -0
  133. package/lib/utils/get-command-name-from-args.js +4 -0
  134. package/lib/utils/get-command-name-from-args.js.map +1 -0
  135. package/lib/utils/js-utils.d.ts +1 -0
  136. package/lib/utils/js-utils.d.ts.map +1 -0
  137. package/lib/utils/js-utils.js +8 -12
  138. package/lib/utils/js-utils.js.map +1 -0
  139. package/lib/utils/miscellaneous.d.ts +9 -48
  140. package/lib/utils/miscellaneous.d.ts.map +1 -0
  141. package/lib/utils/miscellaneous.js +131 -269
  142. package/lib/utils/miscellaneous.js.map +1 -0
  143. package/lib/utils/package.d.ts +2 -0
  144. package/lib/utils/package.d.ts.map +1 -0
  145. package/lib/utils/package.js +4 -0
  146. package/lib/utils/package.js.map +1 -0
  147. package/lib/utils/platform.d.ts +1 -0
  148. package/lib/utils/platform.d.ts.map +1 -0
  149. package/lib/utils/platform.js +5 -9
  150. package/lib/utils/platform.js.map +1 -0
  151. package/lib/utils/proxy-agent.d.ts +3 -0
  152. package/lib/utils/proxy-agent.d.ts.map +1 -0
  153. package/lib/utils/proxy-agent.js +6 -0
  154. package/lib/utils/proxy-agent.js.map +1 -0
  155. package/lib/utils/spinner.d.ts +1 -0
  156. package/lib/utils/spinner.d.ts.map +1 -0
  157. package/lib/utils/spinner.js +8 -10
  158. package/lib/utils/spinner.js.map +1 -0
  159. package/lib/utils/telemetry.d.ts +40 -0
  160. package/lib/utils/telemetry.d.ts.map +1 -0
  161. package/lib/utils/telemetry.js +138 -0
  162. package/lib/utils/telemetry.js.map +1 -0
  163. package/lib/utils/update-version-notifier.d.ts +1 -1
  164. package/lib/utils/update-version-notifier.d.ts.map +1 -0
  165. package/lib/utils/update-version-notifier.js +35 -38
  166. package/lib/utils/update-version-notifier.js.map +1 -0
  167. package/lib/utils/validate-positive-number.d.ts +2 -0
  168. package/lib/utils/validate-positive-number.d.ts.map +1 -0
  169. package/lib/utils/validate-positive-number.js +13 -0
  170. package/lib/utils/validate-positive-number.js.map +1 -0
  171. package/lib/wrapper.d.ts +3 -3
  172. package/lib/wrapper.d.ts.map +1 -0
  173. package/lib/wrapper.js +39 -26
  174. package/lib/wrapper.js.map +1 -0
  175. package/package.json +15 -16
  176. package/CHANGELOG.md +0 -770
  177. package/lib/__mocks__/@redocly/openapi-core.d.ts +0 -99
  178. package/lib/__mocks__/@redocly/openapi-core.js +0 -84
  179. package/lib/__mocks__/documents.d.ts +0 -150
  180. package/lib/__mocks__/documents.js +0 -123
  181. package/lib/__mocks__/fs.d.ts +0 -8
  182. package/lib/__mocks__/fs.js +0 -9
  183. package/lib/__mocks__/perf_hooks.d.ts +0 -3
  184. package/lib/__mocks__/perf_hooks.js +0 -6
  185. package/lib/__mocks__/redoc.d.ts +0 -6
  186. package/lib/__mocks__/redoc.js +0 -5
  187. package/lib/__tests__/commands/build-docs.test.d.ts +0 -1
  188. package/lib/__tests__/commands/build-docs.test.js +0 -54
  189. package/lib/__tests__/commands/bundle.test.d.ts +0 -1
  190. package/lib/__tests__/commands/bundle.test.js +0 -235
  191. package/lib/__tests__/commands/join.test.d.ts +0 -1
  192. package/lib/__tests__/commands/join.test.js +0 -274
  193. package/lib/__tests__/commands/lint.test.d.ts +0 -1
  194. package/lib/__tests__/commands/lint.test.js +0 -149
  195. package/lib/__tests__/commands/push-region.test.d.ts +0 -1
  196. package/lib/__tests__/commands/push-region.test.js +0 -90
  197. package/lib/__tests__/commands/push.test.d.ts +0 -1
  198. package/lib/__tests__/commands/push.test.js +0 -496
  199. package/lib/__tests__/fetch-with-timeout.test.d.ts +0 -1
  200. package/lib/__tests__/fetch-with-timeout.test.js +0 -64
  201. package/lib/__tests__/fixtures/config.d.ts +0 -21
  202. package/lib/__tests__/fixtures/config.js +0 -24
  203. package/lib/__tests__/spinner.test.d.ts +0 -1
  204. package/lib/__tests__/spinner.test.js +0 -43
  205. package/lib/__tests__/utils.test.d.ts +0 -1
  206. package/lib/__tests__/utils.test.js +0 -651
  207. package/lib/__tests__/wrapper.test.d.ts +0 -1
  208. package/lib/__tests__/wrapper.test.js +0 -76
  209. package/lib/auth/__tests__/device-flow.test.d.ts +0 -1
  210. package/lib/auth/__tests__/device-flow.test.js +0 -62
  211. package/lib/auth/__tests__/oauth-client.test.d.ts +0 -1
  212. package/lib/auth/__tests__/oauth-client.test.js +0 -93
  213. package/lib/commands/preview-docs/index.d.ts +0 -12
  214. package/lib/commands/preview-docs/index.js +0 -127
  215. package/lib/commands/preview-docs/preview-server/default.hbs +0 -24
  216. package/lib/commands/preview-docs/preview-server/hot.js +0 -59
  217. package/lib/commands/preview-docs/preview-server/oauth2-redirect.html +0 -21
  218. package/lib/commands/preview-docs/preview-server/preview-server.d.ts +0 -5
  219. package/lib/commands/preview-docs/preview-server/preview-server.js +0 -113
  220. package/lib/commands/preview-docs/preview-server/server.d.ts +0 -22
  221. package/lib/commands/preview-docs/preview-server/server.js +0 -85
  222. package/lib/commands/push.d.ts +0 -44
  223. package/lib/commands/push.js +0 -301
  224. package/lib/commands/split/__tests__/index.test.d.ts +0 -1
  225. package/lib/commands/split/__tests__/index.test.js +0 -91
  226. package/lib/reunite/api/__tests__/api-keys.test.d.ts +0 -1
  227. package/lib/reunite/api/__tests__/api-keys.test.js +0 -26
  228. package/lib/reunite/api/__tests__/api.client.test.d.ts +0 -1
  229. package/lib/reunite/api/__tests__/api.client.test.js +0 -337
  230. package/lib/reunite/api/__tests__/domains.test.d.ts +0 -1
  231. package/lib/reunite/api/__tests__/domains.test.js +0 -32
  232. package/lib/reunite/commands/__tests__/push-status.test.d.ts +0 -1
  233. package/lib/reunite/commands/__tests__/push-status.test.js +0 -563
  234. package/lib/reunite/commands/__tests__/push.test.d.ts +0 -1
  235. package/lib/reunite/commands/__tests__/push.test.js +0 -315
  236. package/lib/reunite/commands/__tests__/utils.test.d.ts +0 -1
  237. package/lib/reunite/commands/__tests__/utils.test.js +0 -51
  238. package/lib/utils/__mocks__/miscellaneous.d.ts +0 -43
  239. package/lib/utils/__mocks__/miscellaneous.js +0 -24
  240. package/lib/utils/getCommandNameFromArgs.js +0 -6
  241. package/src/__mocks__/@redocly/openapi-core.ts +0 -88
  242. package/src/__mocks__/documents.ts +0 -124
  243. package/src/__mocks__/fs.ts +0 -6
  244. package/src/__mocks__/perf_hooks.ts +0 -3
  245. package/src/__mocks__/redoc.ts +0 -2
  246. package/src/__tests__/commands/build-docs.test.ts +0 -59
  247. package/src/__tests__/commands/bundle.test.ts +0 -285
  248. package/src/__tests__/commands/join.test.ts +0 -334
  249. package/src/__tests__/commands/lint.test.ts +0 -190
  250. package/src/__tests__/commands/push-region.test.ts +0 -104
  251. package/src/__tests__/commands/push.test.ts +0 -553
  252. package/src/__tests__/fetch-with-timeout.test.ts +0 -81
  253. package/src/__tests__/fixtures/config.ts +0 -21
  254. package/src/__tests__/fixtures/openapi.json +0 -0
  255. package/src/__tests__/fixtures/openapi.yaml +0 -0
  256. package/src/__tests__/fixtures/redocly.yaml +0 -0
  257. package/src/__tests__/spinner.test.ts +0 -51
  258. package/src/__tests__/utils.test.ts +0 -781
  259. package/src/__tests__/wrapper.test.ts +0 -91
  260. package/src/auth/__tests__/device-flow.test.ts +0 -73
  261. package/src/auth/__tests__/oauth-client.test.ts +0 -117
  262. package/src/auth/device-flow.ts +0 -175
  263. package/src/auth/oauth-client.ts +0 -111
  264. package/src/commands/auth.ts +0 -66
  265. package/src/commands/build-docs/index.ts +0 -55
  266. package/src/commands/build-docs/template.hbs +0 -23
  267. package/src/commands/build-docs/types.ts +0 -25
  268. package/src/commands/build-docs/utils.ts +0 -110
  269. package/src/commands/bundle.ts +0 -154
  270. package/src/commands/eject.ts +0 -42
  271. package/src/commands/join.ts +0 -794
  272. package/src/commands/lint.ts +0 -169
  273. package/src/commands/preview-docs/index.ts +0 -183
  274. package/src/commands/preview-docs/preview-server/default.hbs +0 -24
  275. package/src/commands/preview-docs/preview-server/hot.js +0 -59
  276. package/src/commands/preview-docs/preview-server/oauth2-redirect.html +0 -21
  277. package/src/commands/preview-docs/preview-server/preview-server.ts +0 -159
  278. package/src/commands/preview-docs/preview-server/server.ts +0 -92
  279. package/src/commands/preview-project/constants.ts +0 -23
  280. package/src/commands/preview-project/index.ts +0 -71
  281. package/src/commands/preview-project/types.ts +0 -12
  282. package/src/commands/push.ts +0 -470
  283. package/src/commands/split/__tests__/fixtures/samples.json +0 -61
  284. package/src/commands/split/__tests__/fixtures/spec.json +0 -70
  285. package/src/commands/split/__tests__/fixtures/webhooks.json +0 -85
  286. package/src/commands/split/__tests__/index.test.ts +0 -156
  287. package/src/commands/split/index.ts +0 -397
  288. package/src/commands/split/types.ts +0 -60
  289. package/src/commands/stats.ts +0 -140
  290. package/src/commands/translations.ts +0 -32
  291. package/src/custom.d.ts +0 -1
  292. package/src/index.ts +0 -970
  293. package/src/otel.ts +0 -59
  294. package/src/reunite/api/__tests__/api-keys.test.ts +0 -37
  295. package/src/reunite/api/__tests__/api.client.test.ts +0 -452
  296. package/src/reunite/api/__tests__/domains.test.ts +0 -41
  297. package/src/reunite/api/api-client.ts +0 -381
  298. package/src/reunite/api/api-keys.ts +0 -26
  299. package/src/reunite/api/domains.ts +0 -23
  300. package/src/reunite/api/index.ts +0 -3
  301. package/src/reunite/api/types.ts +0 -108
  302. package/src/reunite/commands/__tests__/push-status.test.ts +0 -653
  303. package/src/reunite/commands/__tests__/push.test.ts +0 -385
  304. package/src/reunite/commands/__tests__/utils.test.ts +0 -62
  305. package/src/reunite/commands/push-status.ts +0 -325
  306. package/src/reunite/commands/push.ts +0 -235
  307. package/src/reunite/commands/utils.ts +0 -66
  308. package/src/reunite/utils.ts +0 -1
  309. package/src/types.ts +0 -64
  310. package/src/utils/__mocks__/miscellaneous.ts +0 -24
  311. package/src/utils/assert-node-version.ts +0 -19
  312. package/src/utils/fetch-with-timeout.ts +0 -30
  313. package/src/utils/getCommandNameFromArgs.ts +0 -5
  314. package/src/utils/js-utils.ts +0 -24
  315. package/src/utils/miscellaneous.ts +0 -729
  316. package/src/utils/platform.ts +0 -31
  317. package/src/utils/spinner.ts +0 -50
  318. package/src/utils/update-version-notifier.ts +0 -115
  319. package/src/wrapper.ts +0 -77
  320. package/tsconfig.json +0 -9
  321. package/tsconfig.tsbuildinfo +0 -1
@@ -1,729 +0,0 @@
1
- import { basename, dirname, extname, join, resolve, relative, isAbsolute } from 'path';
2
- import { blue, gray, green, red, yellow } from 'colorette';
3
- import { performance } from 'perf_hooks';
4
- import * as glob from 'glob';
5
- import * as fs from 'fs';
6
- import * as os from 'os';
7
- import * as readline from 'readline';
8
- import { Writable } from 'stream';
9
- import { execSync } from 'child_process';
10
- import { promisify } from 'util';
11
- import {
12
- ResolveError,
13
- YamlParseError,
14
- parseYaml,
15
- stringifyYaml,
16
- isAbsoluteUrl,
17
- loadConfig,
18
- RedoclyClient,
19
- } from '@redocly/openapi-core';
20
- import {
21
- isEmptyObject,
22
- isNotEmptyArray,
23
- isNotEmptyObject,
24
- isPlainObject,
25
- pluralize,
26
- } from '@redocly/openapi-core/lib/utils';
27
- import { ConfigValidationError } from '@redocly/openapi-core/lib/config';
28
- import { deprecatedRefDocsSchema } from '@redocly/config/lib/reference-docs-config-schema';
29
- import { outputExtensions } from '../types';
30
- import { version } from './update-version-notifier';
31
- import { DESTINATION_REGEX } from '../commands/push';
32
- import { getReuniteUrl } from '../reunite/api';
33
-
34
- import type { Arguments } from 'yargs';
35
- import type {
36
- BundleOutputFormat,
37
- StyleguideConfig,
38
- ResolvedApi,
39
- Region,
40
- Config,
41
- Oas3Definition,
42
- Oas2Definition,
43
- } from '@redocly/openapi-core';
44
- import type { RawConfigProcessor } from '@redocly/openapi-core/lib/config';
45
- import type { Totals, Entrypoint, ConfigApis, CommandOptions, OutputExtensions } from '../types';
46
-
47
- export async function getFallbackApisOrExit(
48
- argsApis: string[] | undefined,
49
- config: ConfigApis
50
- ): Promise<Entrypoint[]> {
51
- const { apis } = config;
52
- const shouldFallbackToAllDefinitions = !isNotEmptyArray(argsApis) && isNotEmptyObject(apis);
53
- const res = shouldFallbackToAllDefinitions
54
- ? fallbackToAllDefinitions(apis, config)
55
- : await expandGlobsInEntrypoints(argsApis!, config);
56
-
57
- const filteredInvalidEntrypoints = res.filter(({ path }) => !isApiPathValid(path));
58
- if (isNotEmptyArray(filteredInvalidEntrypoints)) {
59
- for (const { path } of filteredInvalidEntrypoints) {
60
- process.stderr.write(
61
- yellow(`\n${formatPath(path)} ${red(`does not exist or is invalid.\n\n`)}`)
62
- );
63
- }
64
- exitWithError('Please provide a valid path.');
65
- }
66
- return res;
67
- }
68
-
69
- function getConfigDirectory(config: ConfigApis) {
70
- return config.configFile ? dirname(config.configFile) : process.cwd();
71
- }
72
-
73
- function isApiPathValid(apiPath: string): string | void {
74
- if (!apiPath.trim()) {
75
- exitWithError('Path cannot be empty.');
76
- return;
77
- }
78
- return fs.existsSync(apiPath) || isAbsoluteUrl(apiPath) ? apiPath : undefined;
79
- }
80
-
81
- function fallbackToAllDefinitions(
82
- apis: Record<string, ResolvedApi>,
83
- config: ConfigApis
84
- ): Entrypoint[] {
85
- return Object.entries(apis).map(([alias, { root, output }]) => ({
86
- path: isAbsoluteUrl(root) ? root : resolve(getConfigDirectory(config), root),
87
- alias,
88
- output: output && resolve(getConfigDirectory(config), output),
89
- }));
90
- }
91
-
92
- function getAliasOrPath(config: ConfigApis, aliasOrPath: string): Entrypoint {
93
- const aliasApi = config.apis[aliasOrPath];
94
- return aliasApi
95
- ? {
96
- path: isAbsoluteUrl(aliasApi.root)
97
- ? aliasApi.root
98
- : resolve(getConfigDirectory(config), aliasApi.root),
99
- alias: aliasOrPath,
100
- output: aliasApi.output && resolve(getConfigDirectory(config), aliasApi.output),
101
- }
102
- : {
103
- path: aliasOrPath,
104
- // find alias by path, take the first match
105
- alias:
106
- Object.entries(config.apis).find(([_alias, api]) => {
107
- return resolve(api.root) === resolve(aliasOrPath);
108
- })?.[0] ?? undefined,
109
- };
110
- }
111
-
112
- async function expandGlobsInEntrypoints(argApis: string[], config: ConfigApis) {
113
- return (
114
- await Promise.all(
115
- argApis.map(async (aliasOrPath) => {
116
- return glob.hasMagic(aliasOrPath) && !isAbsoluteUrl(aliasOrPath)
117
- ? (await promisify(glob)(aliasOrPath)).map((g: string) => getAliasOrPath(config, g))
118
- : getAliasOrPath(config, aliasOrPath);
119
- })
120
- )
121
- ).flat();
122
- }
123
-
124
- export function getExecutionTime(startedAt: number) {
125
- return process.env.NODE_ENV === 'test'
126
- ? '<test>ms'
127
- : `${Math.ceil(performance.now() - startedAt)}ms`;
128
- }
129
-
130
- export function printExecutionTime(commandName: string, startedAt: number, api: string) {
131
- const elapsed = getExecutionTime(startedAt);
132
- process.stderr.write(gray(`\n${api}: ${commandName} processed in ${elapsed}\n\n`));
133
- }
134
-
135
- export function pathToFilename(path: string, pathSeparator: string) {
136
- return path
137
- .replace(/~1/g, '/')
138
- .replace(/~0/g, '~')
139
- .replace(/^\//, '')
140
- .replace(/\//g, pathSeparator);
141
- }
142
-
143
- export function escapeLanguageName(lang: string) {
144
- return lang.replace(/#/g, '_sharp').replace(/\//, '_').replace(/\s/g, '');
145
- }
146
-
147
- export function langToExt(lang: string) {
148
- const langObj: any = {
149
- php: '.php',
150
- 'c#': '.cs',
151
- shell: '.sh',
152
- curl: '.sh',
153
- bash: '.sh',
154
- javascript: '.js',
155
- js: '.js',
156
- python: '.py',
157
- c: '.c',
158
- 'c++': '.cpp',
159
- coffeescript: '.litcoffee',
160
- dart: '.dart',
161
- elixir: '.ex',
162
- go: '.go',
163
- groovy: '.groovy',
164
- java: '.java',
165
- kotlin: '.kt',
166
- 'objective-c': '.m',
167
- perl: '.pl',
168
- powershell: '.ps1',
169
- ruby: '.rb',
170
- rust: '.rs',
171
- scala: '.sc',
172
- swift: '.swift',
173
- typescript: '.ts',
174
- tsx: '.tsx',
175
- };
176
- return langObj[lang.toLowerCase()];
177
- }
178
-
179
- export class CircularJSONNotSupportedError extends Error {
180
- constructor(public originalError: Error) {
181
- super(originalError.message);
182
- // Set the prototype explicitly.
183
- Object.setPrototypeOf(this, CircularJSONNotSupportedError.prototype);
184
- }
185
- }
186
-
187
- export function dumpBundle(obj: any, format: BundleOutputFormat, dereference?: boolean): string {
188
- if (format === 'json') {
189
- try {
190
- return JSON.stringify(obj, null, 2);
191
- } catch (e) {
192
- if (e.message.indexOf('circular') > -1) {
193
- throw new CircularJSONNotSupportedError(e);
194
- }
195
- throw e;
196
- }
197
- } else {
198
- return stringifyYaml(obj, {
199
- noRefs: !dereference,
200
- lineWidth: -1,
201
- });
202
- }
203
- }
204
-
205
- export function saveBundle(filename: string, output: string) {
206
- fs.mkdirSync(dirname(filename), { recursive: true });
207
- fs.writeFileSync(filename, output);
208
- }
209
-
210
- export async function promptUser(query: string, hideUserInput = false): Promise<string> {
211
- return new Promise((resolve) => {
212
- let output: Writable = process.stdout;
213
- let isOutputMuted = false;
214
-
215
- if (hideUserInput) {
216
- output = new Writable({
217
- write: (chunk, encoding, callback) => {
218
- if (!isOutputMuted) {
219
- process.stdout.write(chunk, encoding);
220
- }
221
- callback();
222
- },
223
- });
224
- }
225
-
226
- const rl = readline.createInterface({
227
- input: process.stdin,
228
- output,
229
- terminal: true,
230
- historySize: hideUserInput ? 0 : 30,
231
- });
232
-
233
- rl.question(`${query}:\n\n `, (answer) => {
234
- rl.close();
235
- resolve(answer);
236
- });
237
-
238
- isOutputMuted = hideUserInput;
239
- });
240
- }
241
-
242
- export function readYaml(filename: string) {
243
- return parseYaml(fs.readFileSync(filename, 'utf-8'), { filename });
244
- }
245
-
246
- export function writeToFileByExtension(data: unknown, filePath: string, noRefs?: boolean) {
247
- const ext = getAndValidateFileExtension(filePath);
248
-
249
- if (ext === 'json') {
250
- writeJson(data, filePath);
251
- return;
252
- }
253
-
254
- writeYaml(data, filePath, noRefs);
255
- }
256
-
257
- export function writeYaml(data: any, filename: string, noRefs = false) {
258
- const content = stringifyYaml(data, { noRefs });
259
-
260
- if (process.env.NODE_ENV === 'test') {
261
- process.stderr.write(content);
262
- return;
263
- }
264
- fs.mkdirSync(dirname(filename), { recursive: true });
265
- fs.writeFileSync(filename, content);
266
- }
267
-
268
- export function writeJson(data: unknown, filename: string) {
269
- const content = JSON.stringify(data, null, 2);
270
-
271
- if (process.env.NODE_ENV === 'test') {
272
- process.stderr.write(content);
273
- return;
274
- }
275
- fs.mkdirSync(dirname(filename), { recursive: true });
276
- fs.writeFileSync(filename, content);
277
- }
278
-
279
- export function getAndValidateFileExtension(fileName: string): NonNullable<OutputExtensions> {
280
- const ext = fileName.split('.').pop();
281
-
282
- if (['yaml', 'yml', 'json'].includes(ext!)) {
283
- return ext as NonNullable<OutputExtensions>;
284
- }
285
- process.stderr.write(yellow(`Unsupported file extension: ${ext}. Using yaml.\n`));
286
- return 'yaml';
287
- }
288
-
289
- export function handleError(e: Error, ref: string) {
290
- switch (e.constructor) {
291
- case HandledError: {
292
- throw e;
293
- }
294
- case ResolveError:
295
- return exitWithError(`Failed to resolve API description at ${ref}:\n\n - ${e.message}`);
296
- case YamlParseError:
297
- return exitWithError(`Failed to parse API description at ${ref}:\n\n - ${e.message}`);
298
- case CircularJSONNotSupportedError: {
299
- return exitWithError(
300
- `Detected circular reference which can't be converted to JSON.\n` +
301
- `Try to use ${blue('yaml')} output or remove ${blue('--dereferenced')}.`
302
- );
303
- }
304
- case SyntaxError:
305
- return exitWithError(`Syntax error: ${e.message} ${e.stack?.split('\n\n')?.[0]}`);
306
- case ConfigValidationError:
307
- return exitWithError(e.message);
308
- default: {
309
- exitWithError(`Something went wrong when processing ${ref}:\n\n - ${e.message}`);
310
- }
311
- }
312
- }
313
-
314
- export class HandledError extends Error {}
315
-
316
- export function printLintTotals(totals: Totals, definitionsCount: number) {
317
- const ignored = totals.ignored
318
- ? yellow(`${totals.ignored} ${pluralize('problem is', totals.ignored)} explicitly ignored.\n\n`)
319
- : '';
320
-
321
- if (totals.errors > 0) {
322
- process.stderr.write(
323
- red(
324
- `❌ Validation failed with ${totals.errors} ${pluralize('error', totals.errors)}${
325
- totals.warnings > 0
326
- ? ` and ${totals.warnings} ${pluralize('warning', totals.warnings)}`
327
- : ''
328
- }.\n${ignored}`
329
- )
330
- );
331
- } else if (totals.warnings > 0) {
332
- process.stderr.write(
333
- green(`Woohoo! Your API ${pluralize('description is', definitionsCount)} valid. 🎉\n`)
334
- );
335
- process.stderr.write(
336
- yellow(`You have ${totals.warnings} ${pluralize('warning', totals.warnings)}.\n${ignored}`)
337
- );
338
- } else {
339
- process.stderr.write(
340
- green(
341
- `Woohoo! Your API ${pluralize('description is', definitionsCount)} valid. 🎉\n${ignored}`
342
- )
343
- );
344
- }
345
-
346
- if (totals.errors > 0) {
347
- process.stderr.write(
348
- gray(`run \`redocly lint --generate-ignore-file\` to add all problems to the ignore file.\n`)
349
- );
350
- }
351
-
352
- process.stderr.write('\n');
353
- }
354
-
355
- export function printConfigLintTotals(totals: Totals, command?: string | number): void {
356
- if (totals.errors > 0) {
357
- process.stderr.write(
358
- red(`❌ Your config has ${totals.errors} ${pluralize('error', totals.errors)}.`)
359
- );
360
- } else if (totals.warnings > 0) {
361
- process.stderr.write(
362
- yellow(`⚠️ Your config has ${totals.warnings} ${pluralize('warning', totals.warnings)}.\n`)
363
- );
364
- } else if (command === 'check-config') {
365
- process.stderr.write(green('✅ Your config is valid.\n'));
366
- }
367
- }
368
-
369
- export function getOutputFileName({
370
- entrypoint,
371
- output,
372
- argvOutput,
373
- ext,
374
- entries,
375
- }: {
376
- entrypoint: string;
377
- output?: string;
378
- argvOutput?: string;
379
- ext?: BundleOutputFormat;
380
- entries: number;
381
- }) {
382
- let outputFile = output || argvOutput;
383
- if (!outputFile) {
384
- return { ext: ext || 'yaml' };
385
- }
386
-
387
- if (entries > 1 && argvOutput) {
388
- ext = ext || (extname(entrypoint).substring(1) as BundleOutputFormat);
389
- if (!outputExtensions.includes(ext)) {
390
- throw new Error(`Invalid file extension: ${ext}.`);
391
- }
392
- outputFile = join(argvOutput, basename(entrypoint, extname(entrypoint))) + '.' + ext;
393
- } else {
394
- ext =
395
- ext ||
396
- (extname(outputFile).substring(1) as BundleOutputFormat) ||
397
- (extname(entrypoint).substring(1) as BundleOutputFormat);
398
- if (!outputExtensions.includes(ext)) {
399
- throw new Error(`Invalid file extension: ${ext}.`);
400
- }
401
- outputFile = join(dirname(outputFile), basename(outputFile, extname(outputFile))) + '.' + ext;
402
- }
403
- return { outputFile, ext };
404
- }
405
-
406
- export function printUnusedWarnings(config: StyleguideConfig) {
407
- const { preprocessors, rules, decorators } = config.getUnusedRules();
408
- if (rules.length) {
409
- process.stderr.write(
410
- yellow(
411
- `[WARNING] Unused rules found in ${blue(config.configFile || '')}: ${rules.join(', ')}.\n`
412
- )
413
- );
414
- }
415
- if (preprocessors.length) {
416
- process.stderr.write(
417
- yellow(
418
- `[WARNING] Unused preprocessors found in ${blue(
419
- config.configFile || ''
420
- )}: ${preprocessors.join(', ')}.\n`
421
- )
422
- );
423
- }
424
- if (decorators.length) {
425
- process.stderr.write(
426
- yellow(
427
- `[WARNING] Unused decorators found in ${blue(config.configFile || '')}: ${decorators.join(
428
- ', '
429
- )}.\n`
430
- )
431
- );
432
- }
433
-
434
- if (rules.length || preprocessors.length) {
435
- process.stderr.write(`Check the spelling and verify the added plugin prefix.\n`);
436
- }
437
- }
438
-
439
- export function exitWithError(message: string) {
440
- process.stderr.write(red(message) + '\n\n');
441
- throw new HandledError(message);
442
- }
443
-
444
- /**
445
- * Checks if dir is subdir of parent
446
- */
447
- export function isSubdir(parent: string, dir: string): boolean {
448
- const relativePath = relative(parent, dir);
449
- return !!relativePath && !/^..($|\/)/.test(relativePath) && !isAbsolute(relativePath);
450
- }
451
-
452
- export async function loadConfigAndHandleErrors(
453
- options: {
454
- configPath?: string;
455
- customExtends?: string[];
456
- processRawConfig?: RawConfigProcessor;
457
- files?: string[];
458
- region?: Region;
459
- } = {}
460
- ): Promise<Config | void> {
461
- try {
462
- return await loadConfig(options);
463
- } catch (e) {
464
- handleError(e, '');
465
- }
466
- }
467
-
468
- export function sortTopLevelKeysForOas(
469
- document: Oas3Definition | Oas2Definition
470
- ): Oas3Definition | Oas2Definition {
471
- if ('swagger' in document) {
472
- return sortOas2Keys(document);
473
- }
474
- return sortOas3Keys(document as Oas3Definition);
475
- }
476
-
477
- function sortOas2Keys(document: Oas2Definition): Oas2Definition {
478
- const orderedKeys = [
479
- 'swagger',
480
- 'info',
481
- 'host',
482
- 'basePath',
483
- 'schemes',
484
- 'consumes',
485
- 'produces',
486
- 'security',
487
- 'tags',
488
- 'externalDocs',
489
- 'paths',
490
- 'definitions',
491
- 'parameters',
492
- 'responses',
493
- 'securityDefinitions',
494
- ];
495
- const result: any = {};
496
- for (const key of orderedKeys as (keyof Oas2Definition)[]) {
497
- if (document.hasOwnProperty(key)) {
498
- result[key] = document[key];
499
- }
500
- }
501
- // merge any other top-level keys (e.g. vendor extensions)
502
- return Object.assign(result, document);
503
- }
504
- function sortOas3Keys(document: Oas3Definition): Oas3Definition {
505
- const orderedKeys = [
506
- 'openapi',
507
- 'info',
508
- 'jsonSchemaDialect',
509
- 'servers',
510
- 'security',
511
- 'tags',
512
- 'externalDocs',
513
- 'paths',
514
- 'webhooks',
515
- 'x-webhooks',
516
- 'components',
517
- ];
518
- const result: any = {};
519
- for (const key of orderedKeys as (keyof Oas3Definition)[]) {
520
- if (document.hasOwnProperty(key)) {
521
- result[key] = document[key];
522
- }
523
- }
524
- // merge any other top-level keys (e.g. vendor extensions)
525
- return Object.assign(result, document);
526
- }
527
-
528
- export function checkIfRulesetExist(rules: typeof StyleguideConfig.prototype.rules) {
529
- const ruleset = {
530
- ...rules.oas2,
531
- ...rules.oas3_0,
532
- ...rules.oas3_1,
533
- ...rules.async2,
534
- ...rules.async3,
535
- ...rules.arazzo1,
536
- };
537
-
538
- if (isEmptyObject(ruleset)) {
539
- exitWithError(
540
- '⚠️ No rules were configured. Learn how to configure rules: https://redocly.com/docs/cli/rules/'
541
- );
542
- }
543
- }
544
-
545
- export function cleanColors(input: string): string {
546
- // eslint-disable-next-line no-control-regex
547
- return input.replace(/\x1b\[\d+m/g, '');
548
- }
549
-
550
- export async function sendTelemetry(
551
- argv: Arguments | undefined,
552
- exit_code: ExitCode,
553
- has_config: boolean | undefined,
554
- spec_version: string | undefined,
555
- spec_keyword: string | undefined,
556
- spec_full_version: string | undefined
557
- ): Promise<void> {
558
- try {
559
- if (!argv) {
560
- return;
561
- }
562
- const {
563
- _: [command],
564
- $0: _,
565
- ...args
566
- } = argv;
567
- const event_time = new Date().toISOString();
568
- const redoclyClient = new RedoclyClient();
569
- const { RedoclyOAuthClient } = await import('../auth/oauth-client');
570
- const oauthClient = new RedoclyOAuthClient('redocly-cli', version);
571
- const reuniteUrl = getReuniteUrl(argv.residency as string | undefined);
572
- const logged_in = redoclyClient.hasTokens() || (await oauthClient.isAuthorized(reuniteUrl));
573
- const data: Analytics = {
574
- event: 'cli_command',
575
- event_time,
576
- logged_in: logged_in ? 'yes' : 'no',
577
- command: `${command}`,
578
- ...cleanArgs(args, process.argv.slice(2)),
579
- node_version: process.version,
580
- npm_version: execSync('npm -v').toString().replace('\n', ''),
581
- os_platform: os.platform(),
582
- version,
583
- exit_code,
584
- environment: process.env.REDOCLY_ENVIRONMENT,
585
- environment_ci: process.env.CI,
586
- has_config: has_config ? 'yes' : 'no',
587
- spec_version,
588
- spec_keyword,
589
- spec_full_version,
590
- };
591
- const { otelTelemetry } = await import('../otel');
592
- otelTelemetry.init();
593
- otelTelemetry.send(data.command, data);
594
- } catch (err) {
595
- // Do nothing.
596
- }
597
- }
598
-
599
- export type ExitCode = 0 | 1 | 2;
600
-
601
- export type Analytics = {
602
- event: string;
603
- event_time: string;
604
- logged_in: 'yes' | 'no';
605
- command: string;
606
- arguments: string;
607
- node_version: string;
608
- npm_version: string;
609
- os_platform: string;
610
- version: string;
611
- exit_code: ExitCode;
612
- environment?: string;
613
- environment_ci?: string;
614
- raw_input: string;
615
- has_config?: 'yes' | 'no';
616
- spec_version?: string;
617
- spec_keyword?: string;
618
- spec_full_version?: string;
619
- };
620
-
621
- function isFile(value: string) {
622
- return fs.existsSync(value) && fs.statSync(value).isFile();
623
- }
624
-
625
- function isDirectory(value: string) {
626
- return fs.existsSync(value) && fs.statSync(value).isDirectory();
627
- }
628
-
629
- function cleanString(value: string): string {
630
- if (!value) {
631
- return value;
632
- }
633
- if (isAbsoluteUrl(value)) {
634
- return value.split('://')[0] + '://url';
635
- }
636
- if (isFile(value)) {
637
- return value.replace(/.+\.([^.]+)$/, (_, ext) => 'file-' + ext);
638
- }
639
- if (isDirectory(value)) {
640
- return 'folder';
641
- }
642
- if (DESTINATION_REGEX.test(value)) {
643
- return value.startsWith('@') ? '@organization/api-name@api-version' : 'api-name@api-version';
644
- }
645
- return value;
646
- }
647
-
648
- function replaceArgs(
649
- commandInput: string,
650
- targets: string | string[],
651
- replacement: string
652
- ): string {
653
- const targetValues = Array.isArray(targets) ? targets : [targets];
654
- for (const target of targetValues) {
655
- commandInput = commandInput.replaceAll(target, replacement);
656
- }
657
- return commandInput;
658
- }
659
-
660
- export function cleanArgs(parsedArgs: CommandOptions, rawArgv: string[]) {
661
- const KEYS_TO_CLEAN = ['organization', 'o', 'input', 'i', 'client-cert', 'client-key', 'ca-cert'];
662
- let commandInput = rawArgv.join(' ');
663
- const commandArguments: Record<string, string | string[]> = {};
664
- for (const [key, value] of Object.entries(parsedArgs)) {
665
- if (KEYS_TO_CLEAN.includes(key)) {
666
- commandArguments[key] = '***';
667
- commandInput = replaceArgs(commandInput, value, '***');
668
- } else if (typeof value === 'string') {
669
- const cleanedValue = cleanString(value);
670
- commandArguments[key] = cleanedValue;
671
- commandInput = replaceArgs(commandInput, value, cleanedValue);
672
- } else if (Array.isArray(value)) {
673
- commandArguments[key] = value.map(cleanString);
674
- for (const replacedValue of value) {
675
- const newValue = cleanString(replacedValue);
676
- if (commandInput.includes(replacedValue)) {
677
- commandInput = commandInput.replaceAll(replacedValue, newValue);
678
- }
679
- }
680
- } else {
681
- commandArguments[key] = value;
682
- }
683
- }
684
-
685
- return { arguments: JSON.stringify(commandArguments), raw_input: commandInput };
686
- }
687
-
688
- export function checkForDeprecatedOptions<T>(argv: T, deprecatedOptions: Array<keyof T>) {
689
- for (const option of deprecatedOptions) {
690
- if (argv[option]) {
691
- process.stderr.write(
692
- yellow(
693
- `[WARNING] "${String(
694
- option
695
- )}" option is deprecated and will be removed in a future release. \n\n`
696
- )
697
- );
698
- }
699
- }
700
- }
701
-
702
- export function notifyAboutIncompatibleConfigOptions(
703
- themeOpenapiOptions: Record<string, unknown> | undefined
704
- ) {
705
- if (isPlainObject(themeOpenapiOptions)) {
706
- const propertiesSet = Object.keys(themeOpenapiOptions);
707
- const deprecatedSet = Object.keys(deprecatedRefDocsSchema.properties);
708
- const intersection = propertiesSet.filter((prop) => deprecatedSet.includes(prop));
709
- if (intersection.length > 0) {
710
- process.stderr.write(
711
- yellow(
712
- `\n${pluralize('Property', intersection.length)} ${gray(
713
- intersection.map((prop) => `'${prop}'`).join(', ')
714
- )} ${pluralize(
715
- 'is',
716
- intersection.length
717
- )} only used in API Reference Docs and Redoc version 2.x or earlier.\n\n`
718
- )
719
- );
720
- }
721
- }
722
- }
723
-
724
- export function formatPath(path: string) {
725
- if (isAbsoluteUrl(path)) {
726
- return path;
727
- }
728
- return relative(process.cwd(), path);
729
- }