@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
package/src/otel.ts DELETED
@@ -1,59 +0,0 @@
1
- import { trace } from '@opentelemetry/api';
2
- import { Resource as OtelResource } from '@opentelemetry/resources';
3
- import { NodeTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
4
- import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
5
- import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
6
- import { version } from './utils/update-version-notifier';
7
- import { DEFAULT_FETCH_TIMEOUT } from './utils/fetch-with-timeout';
8
-
9
- import type { Analytics } from './utils/miscellaneous';
10
-
11
- type Events = {
12
- [key: string]: Analytics;
13
- };
14
-
15
- const OTEL_TRACES_URL = process.env.OTEL_TRACES_URL || 'https://otel.cloud.redocly.com/v1/traces';
16
-
17
- export class OtelServerTelemetry {
18
- init() {
19
- const nodeTracerProvider = new NodeTracerProvider({
20
- resource: new OtelResource({
21
- [ATTR_SERVICE_NAME]: `redocly-cli`,
22
- [ATTR_SERVICE_VERSION]: `@redocly/cli@${version}`,
23
- }),
24
- });
25
-
26
- nodeTracerProvider.addSpanProcessor(
27
- new SimpleSpanProcessor(
28
- new OTLPTraceExporter({
29
- url: OTEL_TRACES_URL,
30
- headers: {},
31
- timeoutMillis: DEFAULT_FETCH_TIMEOUT,
32
- })
33
- )
34
- );
35
-
36
- nodeTracerProvider.register();
37
- }
38
-
39
- send<K extends keyof Events>(event: K, data: Events[K]): void {
40
- const time = new Date();
41
- const eventId = crypto.randomUUID();
42
- const span = trace.getTracer('CliTelemetry').startSpan(`event.${event}`, {
43
- attributes: {
44
- 'cloudevents.event_client.id': eventId,
45
- 'cloudevents.event_client.type': event,
46
- },
47
- startTime: time,
48
- });
49
- for (const [key, value] of Object.entries(data)) {
50
- const keySnakeCase = key.replace(/([A-Z])/g, '_$1').toLowerCase();
51
- if (value !== undefined) {
52
- span.setAttribute(`cloudevents.event_data.${keySnakeCase}`, value);
53
- }
54
- }
55
- span.end(time);
56
- }
57
- }
58
-
59
- export const otelTelemetry = new OtelServerTelemetry();
@@ -1,37 +0,0 @@
1
- import { getApiKeys } from '../api-keys';
2
- import * as fs from 'fs';
3
-
4
- describe('getApiKeys()', () => {
5
- afterEach(() => {
6
- jest.resetAllMocks();
7
- });
8
-
9
- it('should return api key from environment variable', () => {
10
- process.env.REDOCLY_AUTHORIZATION = 'test-api-key';
11
-
12
- expect(getApiKeys('test-domain')).toEqual('test-api-key');
13
- });
14
-
15
- it('should return api key from credentials file', () => {
16
- process.env.REDOCLY_AUTHORIZATION = '';
17
-
18
- jest.spyOn(fs, 'existsSync').mockReturnValue(true);
19
- jest.spyOn(fs, 'readFileSync').mockReturnValue(
20
- JSON.stringify({
21
- ['test-domain']: 'test-api-key-from-credentials-file',
22
- })
23
- );
24
-
25
- expect(getApiKeys('test-domain')).toEqual('test-api-key-from-credentials-file');
26
- });
27
-
28
- it('should throw an error if no api key provided', () => {
29
- process.env.REDOCLY_AUTHORIZATION = '';
30
-
31
- jest.spyOn(fs, 'existsSync').mockReturnValue(false);
32
-
33
- expect(() => getApiKeys('test-domain')).toThrowError(
34
- 'No api key provided, please use environment variable REDOCLY_AUTHORIZATION.'
35
- );
36
- });
37
- });
@@ -1,452 +0,0 @@
1
- import { red, yellow } from 'colorette';
2
-
3
- import { ReuniteApi, PushPayload, ReuniteApiError } from '../api-client';
4
-
5
- const originalFetch = global.fetch;
6
-
7
- beforeAll(() => {
8
- // Reset fetch mock before each test
9
- global.fetch = jest.fn();
10
- });
11
-
12
- afterAll(() => {
13
- // Restore original fetch after each test
14
- global.fetch = originalFetch;
15
- });
16
-
17
- function mockFetchResponse(response: any) {
18
- (global.fetch as jest.Mock).mockResolvedValue(response);
19
- }
20
-
21
- describe('ApiClient', () => {
22
- const testToken = 'test-token';
23
- const testDomain = 'test-domain.com';
24
- const testOrg = 'test-org';
25
- const testProject = 'test-project';
26
- const version = '1.0.0';
27
- const command = 'push';
28
- const expectedUserAgent = `redocly-cli/${version} ${command}`;
29
-
30
- describe('getDefaultBranch()', () => {
31
- let apiClient: ReuniteApi;
32
-
33
- beforeEach(() => {
34
- apiClient = new ReuniteApi({ domain: testDomain, apiKey: testToken, version, command });
35
- });
36
-
37
- it('should get default project branch', async () => {
38
- mockFetchResponse({
39
- ok: true,
40
- json: jest.fn().mockResolvedValue({
41
- branchName: 'test-branch',
42
- }),
43
- });
44
-
45
- const result = await apiClient.remotes.getDefaultBranch(testOrg, testProject);
46
-
47
- expect(global.fetch).toHaveBeenCalledWith(
48
- `${testDomain}/api/orgs/${testOrg}/projects/${testProject}/source`,
49
- {
50
- method: 'GET',
51
- headers: {
52
- 'Content-Type': 'application/json',
53
- Authorization: `Bearer ${testToken}`,
54
- 'user-agent': expectedUserAgent,
55
- },
56
- signal: expect.any(Object),
57
- }
58
- );
59
-
60
- expect(result).toEqual('test-branch');
61
- });
62
-
63
- it('should throw parsed error if response is not ok', async () => {
64
- mockFetchResponse({
65
- ok: false,
66
- json: jest.fn().mockResolvedValue({
67
- type: 'about:blank',
68
- title: 'Project source not found',
69
- status: 404,
70
- detail: 'Not Found',
71
- object: 'problem',
72
- }),
73
- });
74
-
75
- await expect(apiClient.remotes.getDefaultBranch(testOrg, testProject)).rejects.toThrow(
76
- new ReuniteApiError('Failed to fetch default branch. Project source not found.', 404)
77
- );
78
- });
79
-
80
- it('should throw statusText error if response is not ok', async () => {
81
- mockFetchResponse({
82
- ok: false,
83
- statusText: 'Not found',
84
- json: jest.fn().mockResolvedValue({
85
- unknownField: 'unknown-error',
86
- }),
87
- });
88
-
89
- await expect(apiClient.remotes.getDefaultBranch(testOrg, testProject)).rejects.toThrow(
90
- new ReuniteApiError('Failed to fetch default branch. Not found.', 404)
91
- );
92
- });
93
- });
94
-
95
- describe('upsert()', () => {
96
- const remotePayload = {
97
- mountBranchName: 'remote-mount-branch-name',
98
- mountPath: 'remote-mount-path',
99
- };
100
-
101
- const responseMock = {
102
- id: 'remote-id',
103
- type: 'CICD',
104
- mountPath: 'remote-mount-path',
105
- mountBranchName: 'remote-mount-branch-name',
106
- organizationId: testOrg,
107
- projectId: testProject,
108
- };
109
-
110
- let apiClient: ReuniteApi;
111
-
112
- beforeEach(() => {
113
- apiClient = new ReuniteApi({ domain: testDomain, apiKey: testToken, version, command });
114
- });
115
-
116
- it('should upsert remote', async () => {
117
- mockFetchResponse({
118
- ok: true,
119
- json: jest.fn().mockResolvedValue(responseMock),
120
- });
121
-
122
- const result = await apiClient.remotes.upsert(testOrg, testProject, remotePayload);
123
-
124
- expect(global.fetch).toHaveBeenCalledWith(
125
- `${testDomain}/api/orgs/${testOrg}/projects/${testProject}/remotes`,
126
- {
127
- method: 'POST',
128
- headers: {
129
- 'Content-Type': 'application/json',
130
- Authorization: `Bearer ${testToken}`,
131
- 'user-agent': expectedUserAgent,
132
- },
133
- body: JSON.stringify({
134
- mountPath: remotePayload.mountPath,
135
- mountBranchName: remotePayload.mountBranchName,
136
- type: 'CICD',
137
- autoMerge: true,
138
- }),
139
- signal: expect.any(Object),
140
- agent: undefined,
141
- }
142
- );
143
-
144
- expect(result).toEqual(responseMock);
145
- });
146
-
147
- it('should throw parsed error if response is not ok', async () => {
148
- mockFetchResponse({
149
- ok: false,
150
- json: jest.fn().mockResolvedValue({
151
- type: 'about:blank',
152
- title: 'Not allowed to mount remote outside of project content path: /docs',
153
- status: 403,
154
- detail: 'Forbidden',
155
- object: 'problem',
156
- }),
157
- });
158
-
159
- await expect(apiClient.remotes.upsert(testOrg, testProject, remotePayload)).rejects.toThrow(
160
- new ReuniteApiError(
161
- 'Failed to upsert remote. Not allowed to mount remote outside of project content path: /docs.',
162
- 403
163
- )
164
- );
165
- });
166
-
167
- it('should throw statusText error if response is not ok', async () => {
168
- mockFetchResponse({
169
- ok: false,
170
- status: 404,
171
- statusText: 'Not found',
172
- json: jest.fn().mockResolvedValue({
173
- unknownField: 'unknown-error',
174
- }),
175
- });
176
-
177
- await expect(apiClient.remotes.upsert(testOrg, testProject, remotePayload)).rejects.toThrow(
178
- new ReuniteApiError('Failed to upsert remote. Not found.', 404)
179
- );
180
- });
181
- });
182
-
183
- describe('push()', () => {
184
- const testRemoteId = 'test-remote-id';
185
- const pushPayload = {
186
- remoteId: testRemoteId,
187
- commit: {
188
- message: 'test-message',
189
- author: {
190
- name: 'test-name',
191
- email: 'test-email',
192
- },
193
- branchName: 'test-branch-name',
194
- },
195
- } as unknown as PushPayload;
196
-
197
- const filesMock = [{ path: 'some-file.yaml', stream: Buffer.from('fefef') }];
198
-
199
- const responseMock = {
200
- branchName: 'rem/cicd/rem_01he7sr6ys2agb7w0g9t7978fn-main',
201
- hasChanges: true,
202
- files: [
203
- {
204
- type: 'file',
205
- name: 'some-file.yaml',
206
- path: 'docs/remotes/some-file.yaml',
207
- lastModified: 1698925132394.2993,
208
- mimeType: 'text/yaml',
209
- },
210
- ],
211
- commitSha: 'bb23a2f8e012ac0b7b9961b57fb40d8686b21b43',
212
- outdated: false,
213
- };
214
-
215
- let apiClient: ReuniteApi;
216
-
217
- beforeEach(() => {
218
- apiClient = new ReuniteApi({ domain: testDomain, apiKey: testToken, version, command });
219
- });
220
-
221
- it('should push to remote', async () => {
222
- let passedFormData: FormData = new FormData();
223
-
224
- (fetch as jest.MockedFunction<typeof fetch>).mockImplementationOnce(
225
- async (_: any, options: any): Promise<Response> => {
226
- passedFormData = options.body as FormData;
227
- return {
228
- ok: true,
229
- json: jest.fn().mockResolvedValue(responseMock),
230
- } as unknown as Response;
231
- }
232
- );
233
-
234
- const formData = new globalThis.FormData();
235
-
236
- formData.append('remoteId', testRemoteId);
237
- formData.append('commit[message]', pushPayload.commit.message);
238
- formData.append('commit[author][name]', pushPayload.commit.author.name);
239
- formData.append('commit[author][email]', pushPayload.commit.author.email);
240
- formData.append('commit[branchName]', pushPayload.commit.branchName);
241
- formData.append('files[some-file.yaml]', new Blob([filesMock[0].stream]));
242
-
243
- const result = await apiClient.remotes.push(testOrg, testProject, pushPayload, filesMock);
244
-
245
- expect(fetch).toHaveBeenCalledWith(
246
- `${testDomain}/api/orgs/${testOrg}/projects/${testProject}/pushes`,
247
- expect.objectContaining({
248
- method: 'POST',
249
- headers: {
250
- Authorization: `Bearer ${testToken}`,
251
- 'user-agent': expectedUserAgent,
252
- },
253
- })
254
- );
255
- expect(passedFormData).toEqual(formData);
256
- expect(result).toEqual(responseMock);
257
- });
258
-
259
- it('should throw parsed error if response is not ok', async () => {
260
- mockFetchResponse({
261
- ok: false,
262
- json: jest.fn().mockResolvedValue({
263
- type: 'about:blank',
264
- title: 'Cannot push to remote',
265
- status: 403,
266
- detail: 'Forbidden',
267
- object: 'problem',
268
- }),
269
- });
270
-
271
- await expect(
272
- apiClient.remotes.push(testOrg, testProject, pushPayload, filesMock)
273
- ).rejects.toThrow(new ReuniteApiError('Failed to push. Cannot push to remote.', 403));
274
- });
275
-
276
- it('should throw statusText error if response is not ok', async () => {
277
- mockFetchResponse({
278
- ok: false,
279
- status: 404,
280
- statusText: 'Not found',
281
- json: jest.fn().mockResolvedValue({
282
- unknownField: 'unknown-error',
283
- }),
284
- });
285
-
286
- await expect(
287
- apiClient.remotes.push(testOrg, testProject, pushPayload, filesMock)
288
- ).rejects.toThrow(new ReuniteApiError('Failed to push. Not found.', 404));
289
- });
290
- });
291
-
292
- describe('Sunset header', () => {
293
- const upsertRemoteMock = {
294
- requestFn: () =>
295
- apiClient.remotes.upsert(testOrg, testProject, {
296
- mountBranchName: 'remote-mount-branch-name',
297
- mountPath: 'remote-mount-path',
298
- }),
299
- responseBody: {
300
- id: 'remote-id',
301
- type: 'CICD',
302
- mountPath: 'remote-mount-path',
303
- mountBranchName: 'remote-mount-branch-name',
304
- organizationId: testOrg,
305
- projectId: testProject,
306
- },
307
- };
308
-
309
- const getDefaultBranchMock = {
310
- requestFn: () => apiClient.remotes.getDefaultBranch(testOrg, testProject),
311
- responseBody: {
312
- branchName: 'test-branch',
313
- },
314
- };
315
-
316
- const pushMock = {
317
- requestFn: () =>
318
- apiClient.remotes.push(
319
- testOrg,
320
- testProject,
321
- {
322
- remoteId: 'test-remote-id',
323
- commit: {
324
- message: 'test-message',
325
- author: {
326
- name: 'test-name',
327
- email: 'test-email',
328
- },
329
- branchName: 'test-branch-name',
330
- },
331
- },
332
- [{ path: 'some-file.yaml', stream: Buffer.from('text content') }]
333
- ),
334
- responseBody: {
335
- branchName: 'rem/cicd/rem_01he7sr6ys2agb7w0g9t7978fn-main',
336
- hasChanges: true,
337
- files: [
338
- {
339
- type: 'file',
340
- name: 'some-file.yaml',
341
- path: 'docs/remotes/some-file.yaml',
342
- lastModified: 1698925132394.2993,
343
- mimeType: 'text/yaml',
344
- },
345
- ],
346
- commitSha: 'bb23a2f8e012ac0b7b9961b57fb40d8686b21b43',
347
- outdated: false,
348
- },
349
- };
350
-
351
- const endpointMocks = [upsertRemoteMock, getDefaultBranchMock, pushMock];
352
-
353
- let apiClient: ReuniteApi;
354
-
355
- beforeEach(() => {
356
- apiClient = new ReuniteApi({ domain: testDomain, apiKey: testToken, version, command });
357
- });
358
-
359
- it.each(endpointMocks)(
360
- 'should report endpoint sunset in the past',
361
- async ({ responseBody, requestFn }) => {
362
- jest.spyOn(process.stdout, 'write').mockImplementationOnce(() => true);
363
- const sunsetDate = new Date('2024-09-06T12:30:32.456Z');
364
-
365
- mockFetchResponse({
366
- ok: true,
367
- json: jest.fn().mockResolvedValue(responseBody),
368
- headers: new Headers({
369
- Sunset: sunsetDate.toISOString(),
370
- }),
371
- });
372
-
373
- await requestFn();
374
- apiClient.reportSunsetWarnings();
375
-
376
- expect(process.stdout.write).toHaveBeenCalledWith(
377
- red(
378
- `The "push" command is not compatible with your version of Redocly CLI. Update to the latest version by running "npm install @redocly/cli@latest".\n\n`
379
- )
380
- );
381
- }
382
- );
383
-
384
- it.each(endpointMocks)(
385
- 'should report endpoint sunset in the future',
386
- async ({ responseBody, requestFn }) => {
387
- jest.spyOn(process.stdout, 'write').mockImplementationOnce(() => true);
388
- const sunsetDate = new Date(Date.now() + 1000 * 60 * 60 * 24);
389
-
390
- mockFetchResponse({
391
- ok: true,
392
- json: jest.fn().mockResolvedValue(responseBody),
393
- headers: new Headers({
394
- Sunset: sunsetDate.toISOString(),
395
- }),
396
- });
397
-
398
- await requestFn();
399
- apiClient.reportSunsetWarnings();
400
-
401
- expect(process.stdout.write).toHaveBeenCalledWith(
402
- yellow(
403
- `The "push" command will be incompatible with your version of Redocly CLI after ${sunsetDate.toLocaleString()}. Update to the latest version by running "npm install @redocly/cli@latest".\n\n`
404
- )
405
- );
406
- }
407
- );
408
-
409
- it('should report only expired resource', async () => {
410
- jest.spyOn(process.stdout, 'write').mockImplementationOnce(() => true);
411
-
412
- mockFetchResponse({
413
- ok: true,
414
- json: jest.fn().mockResolvedValue(upsertRemoteMock.responseBody),
415
- headers: new Headers({
416
- Sunset: new Date('2024-08-06T12:30:32.456Z').toISOString(),
417
- }),
418
- });
419
-
420
- await upsertRemoteMock.requestFn();
421
-
422
- mockFetchResponse({
423
- ok: true,
424
- json: jest.fn().mockResolvedValue(getDefaultBranchMock.responseBody),
425
- headers: new Headers({
426
- Sunset: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(),
427
- }),
428
- });
429
-
430
- await getDefaultBranchMock.requestFn();
431
-
432
- mockFetchResponse({
433
- ok: true,
434
- json: jest.fn().mockResolvedValue(pushMock.responseBody),
435
- headers: new Headers({
436
- Sunset: new Date('2024-08-06T12:30:32.456Z').toISOString(),
437
- }),
438
- });
439
-
440
- await pushMock.requestFn();
441
-
442
- apiClient.reportSunsetWarnings();
443
-
444
- expect(process.stdout.write).toHaveBeenCalledTimes(1);
445
- expect(process.stdout.write).toHaveBeenCalledWith(
446
- red(
447
- `The "push" command is not compatible with your version of Redocly CLI. Update to the latest version by running "npm install @redocly/cli@latest".\n\n`
448
- )
449
- );
450
- });
451
- });
452
- });
@@ -1,41 +0,0 @@
1
- import { getDomain } from '../domains';
2
- import { getReuniteUrl } from '../domains';
3
-
4
- import type { Region } from '@redocly/openapi-core';
5
-
6
- describe('getDomain()', () => {
7
- afterEach(() => {
8
- delete process.env.REDOCLY_DOMAIN;
9
- });
10
-
11
- it('should return the domain from environment variable', () => {
12
- process.env.REDOCLY_DOMAIN = 'test-domain';
13
-
14
- expect(getDomain()).toBe('test-domain');
15
- });
16
-
17
- it('should return the default domain if no domain provided', () => {
18
- process.env.REDOCLY_DOMAIN = '';
19
-
20
- expect(getDomain()).toBe('https://app.cloud.redocly.com');
21
- });
22
- });
23
-
24
- describe('getReuniteUrl()', () => {
25
- it('should return US API URL when US region specified', () => {
26
- expect(getReuniteUrl('us')).toBe('https://app.cloud.redocly.com/api');
27
- });
28
-
29
- it('should return EU API URL when EU region specified', () => {
30
- expect(getReuniteUrl('eu')).toBe('https://app.cloud.eu.redocly.com/api');
31
- });
32
-
33
- it('should return custom domain API URL when custom domain specified', () => {
34
- const customDomain = 'https://custom.domain.com';
35
- expect(getReuniteUrl(customDomain as Region)).toBe('https://custom.domain.com/api');
36
- });
37
-
38
- it('should return US API URL when no region specified', () => {
39
- expect(getReuniteUrl()).toBe('https://app.cloud.redocly.com/api');
40
- });
41
- });