@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.
- package/README.md +34 -3
- package/bin/cli.js +1 -1
- package/lib/auth/device-flow.d.ts +1 -0
- package/lib/auth/device-flow.d.ts.map +1 -0
- package/lib/auth/device-flow.js +15 -17
- package/lib/auth/device-flow.js.map +1 -0
- package/lib/auth/oauth-client.d.ts +1 -0
- package/lib/auth/oauth-client.d.ts.map +1 -0
- package/lib/auth/oauth-client.js +21 -23
- package/lib/auth/oauth-client.js.map +1 -0
- package/lib/commands/auth.d.ts +3 -5
- package/lib/commands/auth.d.ts.map +1 -0
- package/lib/commands/auth.js +19 -44
- package/lib/commands/auth.js.map +1 -0
- package/lib/commands/build-docs/index.d.ts +4 -3
- package/lib/commands/build-docs/index.d.ts.map +1 -0
- package/lib/commands/build-docs/index.js +23 -24
- package/lib/commands/build-docs/index.js.map +1 -0
- package/lib/commands/build-docs/types.d.ts +2 -1
- package/lib/commands/build-docs/types.d.ts.map +1 -0
- package/lib/commands/build-docs/types.js +2 -2
- package/lib/commands/build-docs/types.js.map +1 -0
- package/lib/commands/build-docs/utils.d.ts +3 -2
- package/lib/commands/build-docs/utils.d.ts.map +1 -0
- package/lib/commands/build-docs/utils.js +35 -37
- package/lib/commands/build-docs/utils.js.map +1 -0
- package/lib/commands/bundle.d.ts +6 -3
- package/lib/commands/bundle.d.ts.map +1 -0
- package/lib/commands/bundle.js +34 -38
- package/lib/commands/bundle.js.map +1 -0
- package/lib/commands/eject.d.ts +3 -2
- package/lib/commands/eject.d.ts.map +1 -0
- package/lib/commands/eject.js +11 -13
- package/lib/commands/eject.js.map +1 -0
- package/lib/commands/join.d.ts +4 -3
- package/lib/commands/join.d.ts.map +1 -0
- package/lib/commands/join.js +79 -81
- package/lib/commands/join.js.map +1 -0
- package/lib/commands/lint.d.ts +8 -6
- package/lib/commands/lint.d.ts.map +1 -0
- package/lib/commands/lint.js +53 -62
- package/lib/commands/lint.js.map +1 -0
- package/lib/commands/preview-project/constants.d.ts +2 -1
- package/lib/commands/preview-project/constants.d.ts.map +1 -0
- package/lib/commands/preview-project/constants.js +4 -6
- package/lib/commands/preview-project/constants.js.map +1 -0
- package/lib/commands/preview-project/index.d.ts +3 -2
- package/lib/commands/preview-project/index.d.ts.map +1 -0
- package/lib/commands/preview-project/index.js +21 -23
- package/lib/commands/preview-project/index.js.map +1 -0
- package/lib/commands/preview-project/types.d.ts +3 -2
- package/lib/commands/preview-project/types.d.ts.map +1 -0
- package/lib/commands/preview-project/types.js +2 -2
- package/lib/commands/preview-project/types.js.map +1 -0
- package/lib/commands/split/index.d.ts +4 -3
- package/lib/commands/split/index.d.ts.map +1 -0
- package/lib/commands/split/index.js +53 -57
- package/lib/commands/split/index.js.map +1 -0
- package/lib/commands/split/types.d.ts +2 -2
- package/lib/commands/split/types.d.ts.map +1 -0
- package/lib/commands/split/types.js +11 -13
- package/lib/commands/split/types.js.map +1 -0
- package/lib/commands/stats.d.ts +3 -2
- package/lib/commands/stats.d.ts.map +1 -0
- package/lib/commands/stats.js +21 -24
- package/lib/commands/stats.js.map +1 -0
- package/lib/commands/translations.d.ts +3 -2
- package/lib/commands/translations.d.ts.map +1 -0
- package/lib/commands/translations.js +11 -13
- package/lib/commands/translations.js.map +1 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +109 -239
- package/lib/index.js.map +1 -0
- package/lib/otel.d.ts +2 -1
- package/lib/otel.d.ts.map +1 -0
- package/lib/otel.js +22 -23
- package/lib/otel.js.map +1 -0
- package/lib/reunite/api/api-client.d.ts +4 -3
- package/lib/reunite/api/api-client.d.ts.map +1 -0
- package/lib/reunite/api/api-client.js +14 -20
- package/lib/reunite/api/api-client.js.map +1 -0
- package/lib/reunite/api/api-keys.d.ts +2 -1
- package/lib/reunite/api/api-keys.d.ts.map +1 -0
- package/lib/reunite/api/api-keys.js +4 -20
- package/lib/reunite/api/api-keys.js.map +1 -0
- package/lib/reunite/api/domains.d.ts +5 -2
- package/lib/reunite/api/domains.d.ts.map +1 -0
- package/lib/reunite/api/domains.js +6 -15
- package/lib/reunite/api/domains.js.map +1 -0
- package/lib/reunite/api/index.d.ts +4 -3
- package/lib/reunite/api/index.d.ts.map +1 -0
- package/lib/reunite/api/index.js +4 -19
- package/lib/reunite/api/index.js.map +1 -0
- package/lib/reunite/api/types.d.ts +1 -0
- package/lib/reunite/api/types.d.ts.map +1 -0
- package/lib/reunite/api/types.js +2 -2
- package/lib/reunite/api/types.js.map +1 -0
- package/lib/reunite/commands/push-status.d.ts +6 -5
- package/lib/reunite/commands/push-status.d.ts.map +1 -0
- package/lib/reunite/commands/push-status.js +31 -37
- package/lib/reunite/commands/push-status.js.map +1 -0
- package/lib/reunite/commands/push.d.ts +6 -6
- package/lib/reunite/commands/push.d.ts.map +1 -0
- package/lib/reunite/commands/push.js +31 -40
- package/lib/reunite/commands/push.js.map +1 -0
- package/lib/reunite/commands/utils.d.ts +4 -3
- package/lib/reunite/commands/utils.d.ts.map +1 -0
- package/lib/reunite/commands/utils.js +9 -12
- package/lib/reunite/commands/utils.js.map +1 -0
- package/lib/reunite/utils.d.ts +1 -0
- package/lib/reunite/utils.d.ts.map +1 -0
- package/lib/reunite/utils.js +2 -5
- package/lib/reunite/utils.js.map +1 -0
- package/lib/types.d.ts +15 -27
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -5
- package/lib/types.js.map +1 -0
- package/lib/utils/assert-node-version.d.ts +1 -0
- package/lib/utils/assert-node-version.d.ts.map +1 -0
- package/lib/utils/assert-node-version.js +8 -10
- package/lib/utils/assert-node-version.js.map +1 -0
- package/lib/utils/error.d.ts +4 -0
- package/lib/utils/error.d.ts.map +1 -0
- package/lib/utils/error.js +8 -0
- package/lib/utils/error.js.map +1 -0
- package/lib/utils/fetch-with-timeout.d.ts +1 -0
- package/lib/utils/fetch-with-timeout.d.ts.map +1 -0
- package/lib/utils/fetch-with-timeout.js +6 -8
- package/lib/utils/fetch-with-timeout.js.map +1 -0
- package/lib/utils/{getCommandNameFromArgs.d.ts ā get-command-name-from-args.d.ts} +1 -0
- package/lib/utils/get-command-name-from-args.d.ts.map +1 -0
- package/lib/utils/get-command-name-from-args.js +4 -0
- package/lib/utils/get-command-name-from-args.js.map +1 -0
- package/lib/utils/js-utils.d.ts +1 -0
- package/lib/utils/js-utils.d.ts.map +1 -0
- package/lib/utils/js-utils.js +8 -12
- package/lib/utils/js-utils.js.map +1 -0
- package/lib/utils/miscellaneous.d.ts +9 -48
- package/lib/utils/miscellaneous.d.ts.map +1 -0
- package/lib/utils/miscellaneous.js +131 -269
- package/lib/utils/miscellaneous.js.map +1 -0
- package/lib/utils/package.d.ts +2 -0
- package/lib/utils/package.d.ts.map +1 -0
- package/lib/utils/package.js +4 -0
- package/lib/utils/package.js.map +1 -0
- package/lib/utils/platform.d.ts +1 -0
- package/lib/utils/platform.d.ts.map +1 -0
- package/lib/utils/platform.js +5 -9
- package/lib/utils/platform.js.map +1 -0
- package/lib/utils/proxy-agent.d.ts +3 -0
- package/lib/utils/proxy-agent.d.ts.map +1 -0
- package/lib/utils/proxy-agent.js +6 -0
- package/lib/utils/proxy-agent.js.map +1 -0
- package/lib/utils/spinner.d.ts +1 -0
- package/lib/utils/spinner.d.ts.map +1 -0
- package/lib/utils/spinner.js +8 -10
- package/lib/utils/spinner.js.map +1 -0
- package/lib/utils/telemetry.d.ts +40 -0
- package/lib/utils/telemetry.d.ts.map +1 -0
- package/lib/utils/telemetry.js +138 -0
- package/lib/utils/telemetry.js.map +1 -0
- package/lib/utils/update-version-notifier.d.ts +1 -1
- package/lib/utils/update-version-notifier.d.ts.map +1 -0
- package/lib/utils/update-version-notifier.js +35 -38
- package/lib/utils/update-version-notifier.js.map +1 -0
- package/lib/utils/validate-positive-number.d.ts +2 -0
- package/lib/utils/validate-positive-number.d.ts.map +1 -0
- package/lib/utils/validate-positive-number.js +13 -0
- package/lib/utils/validate-positive-number.js.map +1 -0
- package/lib/wrapper.d.ts +3 -3
- package/lib/wrapper.d.ts.map +1 -0
- package/lib/wrapper.js +39 -26
- package/lib/wrapper.js.map +1 -0
- package/package.json +15 -16
- package/CHANGELOG.md +0 -770
- package/lib/__mocks__/@redocly/openapi-core.d.ts +0 -99
- package/lib/__mocks__/@redocly/openapi-core.js +0 -84
- package/lib/__mocks__/documents.d.ts +0 -150
- package/lib/__mocks__/documents.js +0 -123
- package/lib/__mocks__/fs.d.ts +0 -8
- package/lib/__mocks__/fs.js +0 -9
- package/lib/__mocks__/perf_hooks.d.ts +0 -3
- package/lib/__mocks__/perf_hooks.js +0 -6
- package/lib/__mocks__/redoc.d.ts +0 -6
- package/lib/__mocks__/redoc.js +0 -5
- package/lib/__tests__/commands/build-docs.test.d.ts +0 -1
- package/lib/__tests__/commands/build-docs.test.js +0 -54
- package/lib/__tests__/commands/bundle.test.d.ts +0 -1
- package/lib/__tests__/commands/bundle.test.js +0 -235
- package/lib/__tests__/commands/join.test.d.ts +0 -1
- package/lib/__tests__/commands/join.test.js +0 -274
- package/lib/__tests__/commands/lint.test.d.ts +0 -1
- package/lib/__tests__/commands/lint.test.js +0 -149
- package/lib/__tests__/commands/push-region.test.d.ts +0 -1
- package/lib/__tests__/commands/push-region.test.js +0 -90
- package/lib/__tests__/commands/push.test.d.ts +0 -1
- package/lib/__tests__/commands/push.test.js +0 -496
- package/lib/__tests__/fetch-with-timeout.test.d.ts +0 -1
- package/lib/__tests__/fetch-with-timeout.test.js +0 -64
- package/lib/__tests__/fixtures/config.d.ts +0 -21
- package/lib/__tests__/fixtures/config.js +0 -24
- package/lib/__tests__/spinner.test.d.ts +0 -1
- package/lib/__tests__/spinner.test.js +0 -43
- package/lib/__tests__/utils.test.d.ts +0 -1
- package/lib/__tests__/utils.test.js +0 -651
- package/lib/__tests__/wrapper.test.d.ts +0 -1
- package/lib/__tests__/wrapper.test.js +0 -76
- package/lib/auth/__tests__/device-flow.test.d.ts +0 -1
- package/lib/auth/__tests__/device-flow.test.js +0 -62
- package/lib/auth/__tests__/oauth-client.test.d.ts +0 -1
- package/lib/auth/__tests__/oauth-client.test.js +0 -93
- package/lib/commands/preview-docs/index.d.ts +0 -12
- package/lib/commands/preview-docs/index.js +0 -127
- package/lib/commands/preview-docs/preview-server/default.hbs +0 -24
- package/lib/commands/preview-docs/preview-server/hot.js +0 -59
- package/lib/commands/preview-docs/preview-server/oauth2-redirect.html +0 -21
- package/lib/commands/preview-docs/preview-server/preview-server.d.ts +0 -5
- package/lib/commands/preview-docs/preview-server/preview-server.js +0 -113
- package/lib/commands/preview-docs/preview-server/server.d.ts +0 -22
- package/lib/commands/preview-docs/preview-server/server.js +0 -85
- package/lib/commands/push.d.ts +0 -44
- package/lib/commands/push.js +0 -301
- package/lib/commands/split/__tests__/index.test.d.ts +0 -1
- package/lib/commands/split/__tests__/index.test.js +0 -91
- package/lib/reunite/api/__tests__/api-keys.test.d.ts +0 -1
- package/lib/reunite/api/__tests__/api-keys.test.js +0 -26
- package/lib/reunite/api/__tests__/api.client.test.d.ts +0 -1
- package/lib/reunite/api/__tests__/api.client.test.js +0 -337
- package/lib/reunite/api/__tests__/domains.test.d.ts +0 -1
- package/lib/reunite/api/__tests__/domains.test.js +0 -32
- package/lib/reunite/commands/__tests__/push-status.test.d.ts +0 -1
- package/lib/reunite/commands/__tests__/push-status.test.js +0 -563
- package/lib/reunite/commands/__tests__/push.test.d.ts +0 -1
- package/lib/reunite/commands/__tests__/push.test.js +0 -315
- package/lib/reunite/commands/__tests__/utils.test.d.ts +0 -1
- package/lib/reunite/commands/__tests__/utils.test.js +0 -51
- package/lib/utils/__mocks__/miscellaneous.d.ts +0 -43
- package/lib/utils/__mocks__/miscellaneous.js +0 -24
- package/lib/utils/getCommandNameFromArgs.js +0 -6
- package/src/__mocks__/@redocly/openapi-core.ts +0 -88
- package/src/__mocks__/documents.ts +0 -124
- package/src/__mocks__/fs.ts +0 -6
- package/src/__mocks__/perf_hooks.ts +0 -3
- package/src/__mocks__/redoc.ts +0 -2
- package/src/__tests__/commands/build-docs.test.ts +0 -59
- package/src/__tests__/commands/bundle.test.ts +0 -285
- package/src/__tests__/commands/join.test.ts +0 -334
- package/src/__tests__/commands/lint.test.ts +0 -190
- package/src/__tests__/commands/push-region.test.ts +0 -104
- package/src/__tests__/commands/push.test.ts +0 -553
- package/src/__tests__/fetch-with-timeout.test.ts +0 -81
- package/src/__tests__/fixtures/config.ts +0 -21
- package/src/__tests__/fixtures/openapi.json +0 -0
- package/src/__tests__/fixtures/openapi.yaml +0 -0
- package/src/__tests__/fixtures/redocly.yaml +0 -0
- package/src/__tests__/spinner.test.ts +0 -51
- package/src/__tests__/utils.test.ts +0 -781
- package/src/__tests__/wrapper.test.ts +0 -91
- package/src/auth/__tests__/device-flow.test.ts +0 -73
- package/src/auth/__tests__/oauth-client.test.ts +0 -117
- package/src/auth/device-flow.ts +0 -175
- package/src/auth/oauth-client.ts +0 -111
- package/src/commands/auth.ts +0 -66
- package/src/commands/build-docs/index.ts +0 -55
- package/src/commands/build-docs/template.hbs +0 -23
- package/src/commands/build-docs/types.ts +0 -25
- package/src/commands/build-docs/utils.ts +0 -110
- package/src/commands/bundle.ts +0 -154
- package/src/commands/eject.ts +0 -42
- package/src/commands/join.ts +0 -794
- package/src/commands/lint.ts +0 -169
- package/src/commands/preview-docs/index.ts +0 -183
- package/src/commands/preview-docs/preview-server/default.hbs +0 -24
- package/src/commands/preview-docs/preview-server/hot.js +0 -59
- package/src/commands/preview-docs/preview-server/oauth2-redirect.html +0 -21
- package/src/commands/preview-docs/preview-server/preview-server.ts +0 -159
- package/src/commands/preview-docs/preview-server/server.ts +0 -92
- package/src/commands/preview-project/constants.ts +0 -23
- package/src/commands/preview-project/index.ts +0 -71
- package/src/commands/preview-project/types.ts +0 -12
- package/src/commands/push.ts +0 -470
- package/src/commands/split/__tests__/fixtures/samples.json +0 -61
- package/src/commands/split/__tests__/fixtures/spec.json +0 -70
- package/src/commands/split/__tests__/fixtures/webhooks.json +0 -85
- package/src/commands/split/__tests__/index.test.ts +0 -156
- package/src/commands/split/index.ts +0 -397
- package/src/commands/split/types.ts +0 -60
- package/src/commands/stats.ts +0 -140
- package/src/commands/translations.ts +0 -32
- package/src/custom.d.ts +0 -1
- package/src/index.ts +0 -970
- package/src/otel.ts +0 -59
- package/src/reunite/api/__tests__/api-keys.test.ts +0 -37
- package/src/reunite/api/__tests__/api.client.test.ts +0 -452
- package/src/reunite/api/__tests__/domains.test.ts +0 -41
- package/src/reunite/api/api-client.ts +0 -381
- package/src/reunite/api/api-keys.ts +0 -26
- package/src/reunite/api/domains.ts +0 -23
- package/src/reunite/api/index.ts +0 -3
- package/src/reunite/api/types.ts +0 -108
- package/src/reunite/commands/__tests__/push-status.test.ts +0 -653
- package/src/reunite/commands/__tests__/push.test.ts +0 -385
- package/src/reunite/commands/__tests__/utils.test.ts +0 -62
- package/src/reunite/commands/push-status.ts +0 -325
- package/src/reunite/commands/push.ts +0 -235
- package/src/reunite/commands/utils.ts +0 -66
- package/src/reunite/utils.ts +0 -1
- package/src/types.ts +0 -64
- package/src/utils/__mocks__/miscellaneous.ts +0 -24
- package/src/utils/assert-node-version.ts +0 -19
- package/src/utils/fetch-with-timeout.ts +0 -30
- package/src/utils/getCommandNameFromArgs.ts +0 -5
- package/src/utils/js-utils.ts +0 -24
- package/src/utils/miscellaneous.ts +0 -729
- package/src/utils/platform.ts +0 -31
- package/src/utils/spinner.ts +0 -50
- package/src/utils/update-version-notifier.ts +0 -115
- package/src/wrapper.ts +0 -77
- package/tsconfig.json +0 -9
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { loadConfigAndHandleErrors, sendTelemetry } from '../utils/miscellaneous';
|
|
2
|
-
import * as process from 'process';
|
|
3
|
-
import { commandWrapper } from '../wrapper';
|
|
4
|
-
import { handleLint } from '../commands/lint';
|
|
5
|
-
import { Arguments } from 'yargs';
|
|
6
|
-
import { handlePush, PushOptions } from '../commands/push';
|
|
7
|
-
import { detectSpec } from '@redocly/openapi-core';
|
|
8
|
-
|
|
9
|
-
const mockFetch = jest.fn();
|
|
10
|
-
const originalFetch = global.fetch;
|
|
11
|
-
|
|
12
|
-
jest.mock('../utils/miscellaneous', () => ({
|
|
13
|
-
sendTelemetry: jest.fn(),
|
|
14
|
-
loadConfigAndHandleErrors: jest.fn(),
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
beforeAll(() => {
|
|
18
|
-
global.fetch = mockFetch;
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
afterAll(() => {
|
|
22
|
-
jest.resetAllMocks();
|
|
23
|
-
global.fetch = originalFetch;
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
jest.mock('../commands/lint', () => ({
|
|
27
|
-
handleLint: jest.fn().mockImplementation(({ collectSpecData }) => {
|
|
28
|
-
collectSpecData({ openapi: '3.1.0' });
|
|
29
|
-
}),
|
|
30
|
-
lintConfigCallback: jest.fn(),
|
|
31
|
-
}));
|
|
32
|
-
|
|
33
|
-
describe('commandWrapper', () => {
|
|
34
|
-
it('should send telemetry if there is "telemetry: on" in the config', async () => {
|
|
35
|
-
(loadConfigAndHandleErrors as jest.Mock).mockImplementation(() => {
|
|
36
|
-
return { telemetry: 'on', styleguide: { recommendedFallback: true } };
|
|
37
|
-
});
|
|
38
|
-
(detectSpec as jest.Mock).mockImplementationOnce(() => {
|
|
39
|
-
return 'oas3_1';
|
|
40
|
-
});
|
|
41
|
-
process.env.REDOCLY_TELEMETRY = 'on';
|
|
42
|
-
|
|
43
|
-
const wrappedHandler = commandWrapper(handleLint);
|
|
44
|
-
await wrappedHandler({} as any);
|
|
45
|
-
expect(handleLint).toHaveBeenCalledTimes(1);
|
|
46
|
-
expect(sendTelemetry).toHaveBeenCalledTimes(1);
|
|
47
|
-
expect(sendTelemetry).toHaveBeenCalledWith({}, 0, false, 'oas3_1', 'openapi', '3.1.0');
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should not collect spec version if the file is not parsed to json', async () => {
|
|
51
|
-
(loadConfigAndHandleErrors as jest.Mock).mockImplementation(() => {
|
|
52
|
-
return { telemetry: 'on', styleguide: { recommendedFallback: true } };
|
|
53
|
-
});
|
|
54
|
-
(handleLint as jest.Mock).mockImplementation(({ collectSpecData }) => {
|
|
55
|
-
collectSpecData();
|
|
56
|
-
});
|
|
57
|
-
process.env.REDOCLY_TELEMETRY = 'on';
|
|
58
|
-
|
|
59
|
-
const wrappedHandler = commandWrapper(handleLint);
|
|
60
|
-
await wrappedHandler({} as any);
|
|
61
|
-
expect(handleLint).toHaveBeenCalledTimes(1);
|
|
62
|
-
expect(sendTelemetry).toHaveBeenCalledTimes(1);
|
|
63
|
-
expect(sendTelemetry).toHaveBeenCalledWith({}, 0, false, undefined, undefined, undefined);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('should NOT send telemetry if there is "telemetry: off" in the config', async () => {
|
|
67
|
-
(loadConfigAndHandleErrors as jest.Mock).mockImplementation(() => {
|
|
68
|
-
return { telemetry: 'off', styleguide: { recommendedFallback: true } };
|
|
69
|
-
});
|
|
70
|
-
process.env.REDOCLY_TELEMETRY = 'on';
|
|
71
|
-
|
|
72
|
-
const wrappedHandler = commandWrapper(handleLint);
|
|
73
|
-
await wrappedHandler({} as any);
|
|
74
|
-
expect(handleLint).toHaveBeenCalledTimes(1);
|
|
75
|
-
|
|
76
|
-
expect(sendTelemetry).toHaveBeenCalledTimes(0);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should pass files from arguments to config', async () => {
|
|
80
|
-
const filesToPush = ['test1.yaml', 'test2.yaml'];
|
|
81
|
-
|
|
82
|
-
const loadConfigMock = loadConfigAndHandleErrors as jest.Mock<any, any>;
|
|
83
|
-
|
|
84
|
-
const argv = {
|
|
85
|
-
files: filesToPush,
|
|
86
|
-
} as Arguments<PushOptions>;
|
|
87
|
-
|
|
88
|
-
await commandWrapper(handlePush)(argv);
|
|
89
|
-
expect(loadConfigMock).toHaveBeenCalledWith(expect.objectContaining({ files: filesToPush }));
|
|
90
|
-
});
|
|
91
|
-
});
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { RedoclyOAuthDeviceFlow } from '../device-flow';
|
|
2
|
-
|
|
3
|
-
jest.mock('child_process');
|
|
4
|
-
|
|
5
|
-
describe('RedoclyOAuthDeviceFlow', () => {
|
|
6
|
-
const mockBaseUrl = 'https://test.redocly.com';
|
|
7
|
-
const mockClientName = 'test-client';
|
|
8
|
-
const mockVersion = '1.0.0';
|
|
9
|
-
let flow: RedoclyOAuthDeviceFlow;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
flow = new RedoclyOAuthDeviceFlow(mockBaseUrl, mockClientName, mockVersion);
|
|
13
|
-
jest.resetAllMocks();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('verifyToken', () => {
|
|
17
|
-
it('returns true for valid token', async () => {
|
|
18
|
-
jest.spyOn(flow['apiClient'], 'request').mockResolvedValue({
|
|
19
|
-
json: () => Promise.resolve({ user: { id: '123' } }),
|
|
20
|
-
} as Response);
|
|
21
|
-
|
|
22
|
-
const result = await flow.verifyToken('valid-token');
|
|
23
|
-
expect(result).toBe(true);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('returns false for invalid token', async () => {
|
|
27
|
-
jest.spyOn(flow['apiClient'], 'request').mockRejectedValue(new Error('Invalid token'));
|
|
28
|
-
const result = await flow.verifyToken('invalid-token');
|
|
29
|
-
expect(result).toBe(false);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe('verifyApiKey', () => {
|
|
34
|
-
it('returns true for valid API key', async () => {
|
|
35
|
-
jest.spyOn(flow['apiClient'], 'request').mockResolvedValue({
|
|
36
|
-
json: () => Promise.resolve({ success: true }),
|
|
37
|
-
} as Response);
|
|
38
|
-
|
|
39
|
-
const result = await flow.verifyApiKey('valid-key');
|
|
40
|
-
expect(result).toBe(true);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('returns false for invalid API key', async () => {
|
|
44
|
-
jest.spyOn(flow['apiClient'], 'request').mockRejectedValue(new Error('Invalid API key'));
|
|
45
|
-
const result = await flow.verifyApiKey('invalid-key');
|
|
46
|
-
expect(result).toBe(false);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe('refreshToken', () => {
|
|
51
|
-
it('successfully refreshes token', async () => {
|
|
52
|
-
const mockResponse = {
|
|
53
|
-
access_token: 'new-token',
|
|
54
|
-
refresh_token: 'new-refresh',
|
|
55
|
-
expires_in: 3600,
|
|
56
|
-
};
|
|
57
|
-
jest.spyOn(flow['apiClient'], 'request').mockResolvedValue({
|
|
58
|
-
json: () => Promise.resolve(mockResponse),
|
|
59
|
-
} as Response);
|
|
60
|
-
|
|
61
|
-
const result = await flow.refreshToken('old-refresh-token');
|
|
62
|
-
expect(result).toEqual(mockResponse);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('throws error when refresh fails', async () => {
|
|
66
|
-
jest.spyOn(flow['apiClient'], 'request').mockResolvedValue({
|
|
67
|
-
json: () => Promise.resolve({}),
|
|
68
|
-
} as Response);
|
|
69
|
-
|
|
70
|
-
await expect(flow.refreshToken('invalid-refresh')).rejects.toThrow('Failed to refresh token');
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
});
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { RedoclyOAuthClient } from '../oauth-client';
|
|
2
|
-
import { RedoclyOAuthDeviceFlow } from '../device-flow';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import * as path from 'node:path';
|
|
5
|
-
import * as os from 'node:os';
|
|
6
|
-
|
|
7
|
-
jest.mock('node:fs');
|
|
8
|
-
jest.mock('node:os');
|
|
9
|
-
jest.mock('../device-flow');
|
|
10
|
-
|
|
11
|
-
describe('RedoclyOAuthClient', () => {
|
|
12
|
-
const mockClientName = 'test-client';
|
|
13
|
-
const mockVersion = '1.0.0';
|
|
14
|
-
const mockBaseUrl = 'https://test.redocly.com';
|
|
15
|
-
const mockHomeDir = '/mock/home/dir';
|
|
16
|
-
const mockRedoclyDir = path.join(mockHomeDir, '.redocly');
|
|
17
|
-
let client: RedoclyOAuthClient;
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
jest.resetAllMocks();
|
|
21
|
-
(os.homedir as jest.Mock).mockReturnValue(mockHomeDir);
|
|
22
|
-
process.env.HOME = mockHomeDir;
|
|
23
|
-
client = new RedoclyOAuthClient(mockClientName, mockVersion);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
describe('login', () => {
|
|
27
|
-
it('successfully logs in and saves token', async () => {
|
|
28
|
-
const mockToken = { access_token: 'test-token' };
|
|
29
|
-
const mockDeviceFlow = {
|
|
30
|
-
run: jest.fn().mockResolvedValue(mockToken),
|
|
31
|
-
};
|
|
32
|
-
(RedoclyOAuthDeviceFlow as jest.Mock).mockImplementation(() => mockDeviceFlow);
|
|
33
|
-
|
|
34
|
-
await client.login(mockBaseUrl);
|
|
35
|
-
|
|
36
|
-
expect(mockDeviceFlow.run).toHaveBeenCalled();
|
|
37
|
-
expect(fs.writeFileSync).toHaveBeenCalled();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('throws error when login fails', async () => {
|
|
41
|
-
const mockDeviceFlow = {
|
|
42
|
-
run: jest.fn().mockResolvedValue(null),
|
|
43
|
-
};
|
|
44
|
-
(RedoclyOAuthDeviceFlow as jest.Mock).mockImplementation(() => mockDeviceFlow);
|
|
45
|
-
|
|
46
|
-
await expect(client.login(mockBaseUrl)).rejects.toThrow('Failed to login');
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe('logout', () => {
|
|
51
|
-
it('removes token file if it exists', async () => {
|
|
52
|
-
(fs.existsSync as jest.Mock).mockReturnValue(true);
|
|
53
|
-
|
|
54
|
-
await client.logout();
|
|
55
|
-
|
|
56
|
-
expect(fs.rmSync).toHaveBeenCalledWith(path.join(mockRedoclyDir, 'auth.json'));
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('silently fails if token file does not exist', async () => {
|
|
60
|
-
(fs.existsSync as jest.Mock).mockReturnValue(false);
|
|
61
|
-
|
|
62
|
-
await expect(client.logout()).resolves.not.toThrow();
|
|
63
|
-
expect(fs.rmSync).not.toHaveBeenCalled();
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe('isAuthorized', () => {
|
|
68
|
-
it('verifies API key if provided', async () => {
|
|
69
|
-
const mockDeviceFlow = {
|
|
70
|
-
verifyApiKey: jest.fn().mockResolvedValue(true),
|
|
71
|
-
};
|
|
72
|
-
(RedoclyOAuthDeviceFlow as jest.Mock).mockImplementation(() => mockDeviceFlow);
|
|
73
|
-
|
|
74
|
-
const result = await client.isAuthorized(mockBaseUrl, 'test-api-key');
|
|
75
|
-
|
|
76
|
-
expect(result).toBe(true);
|
|
77
|
-
expect(mockDeviceFlow.verifyApiKey).toHaveBeenCalledWith('test-api-key');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('verifies access token if no API key provided', async () => {
|
|
81
|
-
const mockToken = { access_token: 'test-token' };
|
|
82
|
-
const mockDeviceFlow = {
|
|
83
|
-
verifyToken: jest.fn().mockResolvedValue(true),
|
|
84
|
-
};
|
|
85
|
-
(RedoclyOAuthDeviceFlow as jest.Mock).mockImplementation(() => mockDeviceFlow);
|
|
86
|
-
(fs.readFileSync as jest.Mock).mockReturnValue(
|
|
87
|
-
client['cipher'].update(JSON.stringify(mockToken), 'utf8', 'hex') +
|
|
88
|
-
client['cipher'].final('hex')
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
const result = await client.isAuthorized(mockBaseUrl);
|
|
92
|
-
|
|
93
|
-
expect(result).toBe(true);
|
|
94
|
-
expect(mockDeviceFlow.verifyToken).toHaveBeenCalledWith('test-token');
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('returns false if token refresh fails', async () => {
|
|
98
|
-
const mockToken = {
|
|
99
|
-
access_token: 'old-token',
|
|
100
|
-
refresh_token: 'refresh-token',
|
|
101
|
-
};
|
|
102
|
-
const mockDeviceFlow = {
|
|
103
|
-
verifyToken: jest.fn().mockResolvedValue(false),
|
|
104
|
-
refreshToken: jest.fn().mockRejectedValue(new Error('Refresh failed')),
|
|
105
|
-
};
|
|
106
|
-
(RedoclyOAuthDeviceFlow as jest.Mock).mockImplementation(() => mockDeviceFlow);
|
|
107
|
-
(fs.readFileSync as jest.Mock).mockReturnValue(
|
|
108
|
-
client['cipher'].update(JSON.stringify(mockToken), 'utf8', 'hex') +
|
|
109
|
-
client['cipher'].final('hex')
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
const result = await client.isAuthorized(mockBaseUrl);
|
|
113
|
-
|
|
114
|
-
expect(result).toBe(false);
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
});
|
package/src/auth/device-flow.ts
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { blue, green } from 'colorette';
|
|
2
|
-
import * as childProcess from 'child_process';
|
|
3
|
-
import { ReuniteApiClient } from '../reunite/api/api-client';
|
|
4
|
-
|
|
5
|
-
export type AuthToken = {
|
|
6
|
-
access_token: string;
|
|
7
|
-
refresh_token?: string;
|
|
8
|
-
token_type?: string;
|
|
9
|
-
expires_in?: number;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export class RedoclyOAuthDeviceFlow {
|
|
13
|
-
private apiClient: ReuniteApiClient;
|
|
14
|
-
|
|
15
|
-
constructor(private baseUrl: string, private clientName: string, private version: string) {
|
|
16
|
-
this.apiClient = new ReuniteApiClient(this.version, 'login');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async run() {
|
|
20
|
-
const code = await this.getDeviceCode();
|
|
21
|
-
process.stdout.write(
|
|
22
|
-
'Attempting to automatically open the SSO authorization page in your default browser.\n'
|
|
23
|
-
);
|
|
24
|
-
process.stdout.write(
|
|
25
|
-
'If the browser does not open or you wish to use a different device to authorize this request, open the following URL:\n\n'
|
|
26
|
-
);
|
|
27
|
-
process.stdout.write(blue(code.verificationUri));
|
|
28
|
-
process.stdout.write(`\n\n`);
|
|
29
|
-
process.stdout.write(`Then enter the code:\n\n`);
|
|
30
|
-
process.stdout.write(blue(code.userCode));
|
|
31
|
-
process.stdout.write(`\n\n`);
|
|
32
|
-
|
|
33
|
-
this.openBrowser(code.verificationUriComplete);
|
|
34
|
-
|
|
35
|
-
const accessToken = await this.pollingAccessToken(
|
|
36
|
-
code.deviceCode,
|
|
37
|
-
code.interval,
|
|
38
|
-
code.expiresIn
|
|
39
|
-
);
|
|
40
|
-
process.stdout.write(green('ā
Logged in\n\n'));
|
|
41
|
-
|
|
42
|
-
return accessToken;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
private openBrowser(url: string) {
|
|
46
|
-
try {
|
|
47
|
-
const cmd =
|
|
48
|
-
process.platform === 'win32'
|
|
49
|
-
? `start ${url}`
|
|
50
|
-
: process.platform === 'darwin'
|
|
51
|
-
? `open ${url}`
|
|
52
|
-
: `xdg-open ${url}`;
|
|
53
|
-
|
|
54
|
-
childProcess.execSync(cmd);
|
|
55
|
-
} catch {
|
|
56
|
-
// silently fail if browser cannot be opened
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async verifyToken(accessToken: string) {
|
|
61
|
-
try {
|
|
62
|
-
const response = await this.sendRequest('/session', 'GET', undefined, {
|
|
63
|
-
Cookie: `accessToken=${accessToken};`,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return !!response.user;
|
|
67
|
-
} catch {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async verifyApiKey(apiKey: string) {
|
|
73
|
-
try {
|
|
74
|
-
const response = await this.sendRequest('/api-keys-verify', 'POST', {
|
|
75
|
-
apiKey,
|
|
76
|
-
});
|
|
77
|
-
return !!response.success;
|
|
78
|
-
} catch {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async refreshToken(refreshToken: string) {
|
|
84
|
-
const response = await this.sendRequest(`/device-rotate-token`, 'POST', {
|
|
85
|
-
grant_type: 'refresh_token',
|
|
86
|
-
client_name: this.clientName,
|
|
87
|
-
refresh_token: refreshToken,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
if (!response.access_token) {
|
|
91
|
-
throw new Error('Failed to refresh token');
|
|
92
|
-
}
|
|
93
|
-
return {
|
|
94
|
-
access_token: response.access_token,
|
|
95
|
-
refresh_token: response.refresh_token,
|
|
96
|
-
expires_in: response.expires_in,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private async pollingAccessToken(
|
|
101
|
-
deviceCode: string,
|
|
102
|
-
interval: number,
|
|
103
|
-
expiresIn: number
|
|
104
|
-
): Promise<AuthToken> {
|
|
105
|
-
return new Promise((resolve, reject) => {
|
|
106
|
-
const intervalId = setInterval(async () => {
|
|
107
|
-
const response = await this.getAccessToken(deviceCode);
|
|
108
|
-
if (response.access_token) {
|
|
109
|
-
clearInterval(intervalId);
|
|
110
|
-
clearTimeout(timeoutId);
|
|
111
|
-
resolve(response);
|
|
112
|
-
}
|
|
113
|
-
if (response.error && response.error !== 'authorization_pending') {
|
|
114
|
-
clearInterval(intervalId);
|
|
115
|
-
clearTimeout(timeoutId);
|
|
116
|
-
reject(response.error_description);
|
|
117
|
-
}
|
|
118
|
-
}, interval * 1000);
|
|
119
|
-
|
|
120
|
-
const timeoutId = setTimeout(async () => {
|
|
121
|
-
clearInterval(intervalId);
|
|
122
|
-
clearTimeout(timeoutId);
|
|
123
|
-
reject('Authorization has expired. Please try again.');
|
|
124
|
-
}, expiresIn * 1000);
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private async getAccessToken(deviceCode: string) {
|
|
129
|
-
return await this.sendRequest('/device-token', 'POST', {
|
|
130
|
-
client_name: this.clientName,
|
|
131
|
-
device_code: deviceCode,
|
|
132
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
private async getDeviceCode() {
|
|
137
|
-
const {
|
|
138
|
-
device_code: deviceCode,
|
|
139
|
-
user_code: userCode,
|
|
140
|
-
verification_uri: verificationUri,
|
|
141
|
-
verification_uri_complete: verificationUriComplete,
|
|
142
|
-
interval = 10,
|
|
143
|
-
expires_in: expiresIn = 300,
|
|
144
|
-
} = await this.sendRequest('/device-authorize', 'POST', {
|
|
145
|
-
client_name: this.clientName,
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
deviceCode,
|
|
150
|
-
userCode,
|
|
151
|
-
verificationUri,
|
|
152
|
-
verificationUriComplete,
|
|
153
|
-
interval,
|
|
154
|
-
expiresIn,
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
private async sendRequest(
|
|
159
|
-
url: string,
|
|
160
|
-
method: string = 'GET',
|
|
161
|
-
body: Record<string, unknown> | undefined = undefined,
|
|
162
|
-
headers: Record<string, string> = {}
|
|
163
|
-
) {
|
|
164
|
-
url = `${this.baseUrl}${url}`;
|
|
165
|
-
const response = await this.apiClient.request(url, {
|
|
166
|
-
body: body ? JSON.stringify(body) : body,
|
|
167
|
-
method,
|
|
168
|
-
headers: { 'Content-Type': 'application/json', ...headers },
|
|
169
|
-
});
|
|
170
|
-
if (response.status === 204) {
|
|
171
|
-
return { success: true };
|
|
172
|
-
}
|
|
173
|
-
return await response.json();
|
|
174
|
-
}
|
|
175
|
-
}
|
package/src/auth/oauth-client.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { homedir } from 'node:os';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import { mkdirSync, existsSync, writeFileSync, readFileSync, rmSync } from 'node:fs';
|
|
4
|
-
import * as crypto from 'node:crypto';
|
|
5
|
-
import { Buffer } from 'node:buffer';
|
|
6
|
-
import { type AuthToken, RedoclyOAuthDeviceFlow } from './device-flow';
|
|
7
|
-
|
|
8
|
-
const SALT = '4618dbc9-8aed-4e27-aaf0-225f4603e5a4';
|
|
9
|
-
const CRYPTO_ALGORITHM = 'aes-256-cbc';
|
|
10
|
-
|
|
11
|
-
export class RedoclyOAuthClient {
|
|
12
|
-
private dir: string;
|
|
13
|
-
private cipher: crypto.Cipher;
|
|
14
|
-
private decipher: crypto.Decipher;
|
|
15
|
-
|
|
16
|
-
constructor(private clientName: string, private version: string) {
|
|
17
|
-
this.dir = path.join(homedir(), '.redocly');
|
|
18
|
-
if (!existsSync(this.dir)) {
|
|
19
|
-
mkdirSync(this.dir);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const homeDirPath = process.env.HOME as string;
|
|
23
|
-
const hash = crypto.createHash('sha256');
|
|
24
|
-
hash.update(`${homeDirPath}${SALT}`);
|
|
25
|
-
const hashHex = hash.digest('hex');
|
|
26
|
-
|
|
27
|
-
const key = Buffer.alloc(
|
|
28
|
-
32,
|
|
29
|
-
Buffer.from(hashHex).toString('base64')
|
|
30
|
-
).toString() as crypto.CipherKey;
|
|
31
|
-
const iv = Buffer.alloc(
|
|
32
|
-
16,
|
|
33
|
-
Buffer.from(process.env.HOME as string).toString('base64')
|
|
34
|
-
).toString() as crypto.BinaryLike;
|
|
35
|
-
this.cipher = crypto.createCipheriv(CRYPTO_ALGORITHM, key, iv);
|
|
36
|
-
this.decipher = crypto.createDecipheriv(CRYPTO_ALGORITHM, key, iv);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async login(baseUrl: string) {
|
|
40
|
-
const deviceFlow = new RedoclyOAuthDeviceFlow(baseUrl, this.clientName, this.version);
|
|
41
|
-
|
|
42
|
-
const token = await deviceFlow.run();
|
|
43
|
-
if (!token) {
|
|
44
|
-
throw new Error('Failed to login');
|
|
45
|
-
}
|
|
46
|
-
this.saveToken(token);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async logout() {
|
|
50
|
-
try {
|
|
51
|
-
this.removeToken();
|
|
52
|
-
} catch (err) {
|
|
53
|
-
// do nothing
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async isAuthorized(baseUrl: string, apiKey?: string) {
|
|
58
|
-
const deviceFlow = new RedoclyOAuthDeviceFlow(baseUrl, this.clientName, this.version);
|
|
59
|
-
|
|
60
|
-
if (apiKey) {
|
|
61
|
-
return await deviceFlow.verifyApiKey(apiKey);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const token = await this.readToken();
|
|
65
|
-
if (!token) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const isValidAccessToken = await deviceFlow.verifyToken(token.access_token);
|
|
70
|
-
|
|
71
|
-
if (isValidAccessToken) {
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
const newToken = await deviceFlow.refreshToken(token.refresh_token);
|
|
77
|
-
await this.saveToken(newToken);
|
|
78
|
-
} catch {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private async saveToken(token: AuthToken) {
|
|
86
|
-
try {
|
|
87
|
-
const encrypted =
|
|
88
|
-
this.cipher.update(JSON.stringify(token), 'utf8', 'hex') + this.cipher.final('hex');
|
|
89
|
-
writeFileSync(path.join(this.dir, 'auth.json'), encrypted);
|
|
90
|
-
} catch (error) {
|
|
91
|
-
process.stderr.write('Error saving tokens:', error);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private async readToken() {
|
|
96
|
-
try {
|
|
97
|
-
const token = readFileSync(path.join(this.dir, 'auth.json'), 'utf8');
|
|
98
|
-
const decrypted = this.decipher.update(token, 'hex', 'utf8') + this.decipher.final('utf8');
|
|
99
|
-
return decrypted ? JSON.parse(decrypted) : null;
|
|
100
|
-
} catch {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private async removeToken() {
|
|
106
|
-
const tokenPath = path.join(this.dir, 'auth.json');
|
|
107
|
-
if (existsSync(tokenPath)) {
|
|
108
|
-
rmSync(tokenPath);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
package/src/commands/auth.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { blue, green, gray, yellow } from 'colorette';
|
|
2
|
-
import { RedoclyClient } from '@redocly/openapi-core';
|
|
3
|
-
import { exitWithError, promptUser } from '../utils/miscellaneous';
|
|
4
|
-
import { RedoclyOAuthClient } from '../auth/oauth-client';
|
|
5
|
-
import { getReuniteUrl } from '../reunite/api';
|
|
6
|
-
|
|
7
|
-
import type { CommandArgs } from '../wrapper';
|
|
8
|
-
import type { Region } from '@redocly/openapi-core';
|
|
9
|
-
|
|
10
|
-
export function promptClientToken(domain: string) {
|
|
11
|
-
return promptUser(
|
|
12
|
-
green(
|
|
13
|
-
`\n š Copy your API key from ${blue(`https://app.${domain}/profile`)} and paste it below`
|
|
14
|
-
) + yellow(' (if you want to log in with Reunite, please run `redocly login --next` instead)'),
|
|
15
|
-
true
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type LoginOptions = {
|
|
20
|
-
verbose?: boolean;
|
|
21
|
-
residency?: string;
|
|
22
|
-
config?: string;
|
|
23
|
-
next?: boolean;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export async function handleLogin({ argv, config, version }: CommandArgs<LoginOptions>) {
|
|
27
|
-
if (argv.next) {
|
|
28
|
-
try {
|
|
29
|
-
const reuniteUrl = getReuniteUrl(argv.residency);
|
|
30
|
-
const oauthClient = new RedoclyOAuthClient('redocly-cli', version);
|
|
31
|
-
await oauthClient.login(reuniteUrl);
|
|
32
|
-
} catch {
|
|
33
|
-
if (argv.residency) {
|
|
34
|
-
const reuniteUrl = getReuniteUrl(argv.residency);
|
|
35
|
-
exitWithError(`ā Connection to ${reuniteUrl} failed.`);
|
|
36
|
-
} else {
|
|
37
|
-
exitWithError(`ā Login failed. Please check your credentials and try again.`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
} else {
|
|
41
|
-
try {
|
|
42
|
-
const region = (argv.residency as Region) || config.region;
|
|
43
|
-
const client = new RedoclyClient(region);
|
|
44
|
-
const clientToken = await promptClientToken(client.domain);
|
|
45
|
-
process.stdout.write(gray('\n Logging in...\n'));
|
|
46
|
-
await client.login(clientToken, argv.verbose);
|
|
47
|
-
process.stdout.write(green(' Authorization confirmed. ā
\n\n'));
|
|
48
|
-
} catch (err) {
|
|
49
|
-
exitWithError(' ' + err?.message);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export type LogoutOptions = {
|
|
55
|
-
config?: string;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export async function handleLogout({ version }: CommandArgs<LogoutOptions>) {
|
|
59
|
-
const client = new RedoclyClient();
|
|
60
|
-
client.logout();
|
|
61
|
-
|
|
62
|
-
const oauthClient = new RedoclyOAuthClient('redocly-cli', version);
|
|
63
|
-
oauthClient.logout();
|
|
64
|
-
|
|
65
|
-
process.stdout.write('Logged out from the Redocly account. ā \n');
|
|
66
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { loadAndBundleSpec } from 'redoc';
|
|
2
|
-
import { dirname, resolve } from 'path';
|
|
3
|
-
import { writeFileSync, mkdirSync } from 'fs';
|
|
4
|
-
import { performance } from 'perf_hooks';
|
|
5
|
-
import { getMergedConfig, isAbsoluteUrl } from '@redocly/openapi-core';
|
|
6
|
-
import { getObjectOrJSON, getPageHTML } from './utils';
|
|
7
|
-
import { exitWithError, getExecutionTime, getFallbackApisOrExit } from '../../utils/miscellaneous';
|
|
8
|
-
|
|
9
|
-
import type { BuildDocsArgv } from './types';
|
|
10
|
-
import type { CommandArgs } from '../../wrapper';
|
|
11
|
-
|
|
12
|
-
export const handlerBuildCommand = async ({
|
|
13
|
-
argv,
|
|
14
|
-
config: configFromFile,
|
|
15
|
-
collectSpecData,
|
|
16
|
-
}: CommandArgs<BuildDocsArgv>) => {
|
|
17
|
-
const startedAt = performance.now();
|
|
18
|
-
|
|
19
|
-
const config = getMergedConfig(configFromFile, argv.api);
|
|
20
|
-
const apis = await getFallbackApisOrExit(argv.api ? [argv.api] : [], config);
|
|
21
|
-
const { path: pathToApi } = apis[0];
|
|
22
|
-
|
|
23
|
-
const options = {
|
|
24
|
-
output: argv.o,
|
|
25
|
-
title: argv.title,
|
|
26
|
-
disableGoogleFont: argv.disableGoogleFont,
|
|
27
|
-
templateFileName: argv.template,
|
|
28
|
-
templateOptions: argv.templateOptions || {},
|
|
29
|
-
redocOptions: getObjectOrJSON(argv.theme?.openapi, config),
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const redocCurrentVersion = require('../../../package.json').dependencies.redoc;
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
const elapsed = getExecutionTime(startedAt);
|
|
36
|
-
|
|
37
|
-
const api = await loadAndBundleSpec(isAbsoluteUrl(pathToApi) ? pathToApi : resolve(pathToApi));
|
|
38
|
-
collectSpecData?.(api);
|
|
39
|
-
const pageHTML = await getPageHTML(
|
|
40
|
-
api,
|
|
41
|
-
pathToApi,
|
|
42
|
-
{ ...options, redocCurrentVersion },
|
|
43
|
-
argv.config
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
mkdirSync(dirname(options.output), { recursive: true });
|
|
47
|
-
writeFileSync(options.output, pageHTML);
|
|
48
|
-
const sizeInKiB = Math.ceil(Buffer.byteLength(pageHTML) / 1024);
|
|
49
|
-
process.stdout.write(
|
|
50
|
-
`\nš bundled successfully in: ${options.output} (${sizeInKiB} KiB) [ā± ${elapsed}].\n`
|
|
51
|
-
);
|
|
52
|
-
} catch (e) {
|
|
53
|
-
exitWithError(e);
|
|
54
|
-
}
|
|
55
|
-
};
|