mirror of
https://github.com/LukeHagar/redocly-cli.git
synced 2025-12-06 04:21:09 +00:00
chore: revert 1.10.2 (#1468)
* Revert "fix: fix issues with https-agent-proxy for cli and openapi-core packages (#1461)"
This reverts commit 7ec5cfcd37.
This commit is contained in:
6
.changeset/tall-weeks-crash.md
Normal file
6
.changeset/tall-weeks-crash.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@redocly/openapi-core": patch
|
||||
"@redocly/cli": patch
|
||||
---
|
||||
|
||||
Reverted "Users can run the CLI tool behind a proxy by using HTTP_PROXY or HTTPS_PROXY environment variables to configure the proxy settings" temporary.
|
||||
@@ -78,30 +78,6 @@ To give a Docker container access to your OpenAPI description files, you need to
|
||||
docker run --rm -v $PWD:/spec redocly/cli lint openapi.yaml
|
||||
```
|
||||
|
||||
## Run CLI behind a proxy
|
||||
|
||||
If you need to run the CLI tool behind a proxy, you can use the `HTTP_PROXY` and `HTTPS_PROXY` environment variables to configure the proxy settings. These environment variables are commonly used to specify the proxy server for HTTP and HTTPS traffic, respectively.
|
||||
|
||||
### Set up Proxy Environment Variables
|
||||
|
||||
Before running the CLI behind a proxy, make sure to set the appropriate proxy environment variables. Open a terminal and use the following commands:
|
||||
|
||||
```bash
|
||||
# For HTTP proxy
|
||||
export HTTP_PROXY=http://your-http-proxy-server:port
|
||||
|
||||
# For HTTPS proxy
|
||||
export HTTPS_PROXY=http://your-https-proxy-server:port
|
||||
```
|
||||
|
||||
### Use Environment Variables with CLI Commands
|
||||
|
||||
You can also directly include the proxy environment variables in the command itself. For example:
|
||||
|
||||
```bash
|
||||
HTTPS_PROXY=https://your-https-proxy-server:port redocly lint --extends minimal openapi.yaml
|
||||
```
|
||||
|
||||
## Next steps
|
||||
|
||||
- Set up [autocomplete for Redocly CLI](./guides/autocomplete.md).
|
||||
|
||||
44
package-lock.json
generated
44
package-lock.json
generated
@@ -12945,7 +12945,6 @@
|
||||
"dependencies": {
|
||||
"@redocly/ajv": "^8.11.0",
|
||||
"colorette": "^1.2.0",
|
||||
"https-proxy-agent": "^7.0.4",
|
||||
"js-levenshtein": "^1.1.6",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
@@ -12968,29 +12967,6 @@
|
||||
"node": ">=14.19.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/agent-base": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
|
||||
"integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"packages/core/node_modules/https-proxy-agent": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz",
|
||||
"integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==",
|
||||
"dependencies": {
|
||||
"agent-base": "^7.0.2",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -15634,7 +15610,6 @@
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@types/pluralize": "^0.0.29",
|
||||
"colorette": "^1.2.0",
|
||||
"https-proxy-agent": "^7.0.4",
|
||||
"js-levenshtein": "^1.1.6",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
@@ -15643,25 +15618,6 @@
|
||||
"pluralize": "^8.0.0",
|
||||
"typescript": "^5.2.2",
|
||||
"yaml-ast-parser": "0.0.43"
|
||||
},
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
|
||||
"integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
|
||||
"requires": {
|
||||
"debug": "^4.3.4"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz",
|
||||
"integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==",
|
||||
"requires": {
|
||||
"agent-base": "^7.0.2",
|
||||
"debug": "4"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@sinclair/typebox": {
|
||||
|
||||
@@ -21,7 +21,6 @@ export const __redoclyClient = {
|
||||
export const RedoclyClient = jest.fn(() => __redoclyClient);
|
||||
export const loadConfig = jest.fn(() => ConfigFixture);
|
||||
export const getMergedConfig = jest.fn();
|
||||
export const getProxyAgent = jest.fn();
|
||||
export const lint = jest.fn();
|
||||
export const bundle = jest.fn(() => ({ bundle: { parsed: null }, problems: null }));
|
||||
export const getTotals = jest.fn(() => ({ errors: 0 }));
|
||||
|
||||
@@ -42,7 +42,6 @@ describe('ApiClient', () => {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${testToken}`,
|
||||
},
|
||||
signal: expect.any(Object),
|
||||
}
|
||||
);
|
||||
|
||||
@@ -123,8 +122,6 @@ describe('ApiClient', () => {
|
||||
type: 'CICD',
|
||||
autoMerge: true,
|
||||
}),
|
||||
signal: expect.any(Object),
|
||||
agent: undefined,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fetchWithTimeout from '../../utils/fetch-with-timeout';
|
||||
import fetch from 'node-fetch';
|
||||
import * as FormData from 'form-data';
|
||||
import { getProxyAgent } from '@redocly/openapi-core';
|
||||
|
||||
import type { Response } from 'node-fetch';
|
||||
import type { ReadStream } from 'fs';
|
||||
import type {
|
||||
@@ -25,7 +25,7 @@ class RemotesApiClient {
|
||||
}
|
||||
|
||||
async getDefaultBranch(organizationId: string, projectId: string) {
|
||||
const response = await fetchWithTimeout(
|
||||
const response = await fetch(
|
||||
`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/source`,
|
||||
{
|
||||
method: 'GET',
|
||||
@@ -36,10 +36,6 @@ class RemotesApiClient {
|
||||
}
|
||||
);
|
||||
|
||||
if (!response) {
|
||||
throw new Error(`Failed to get default branch.`);
|
||||
}
|
||||
|
||||
try {
|
||||
const source = await this.getParsedResponse<ProjectSourceResponse>(response);
|
||||
|
||||
@@ -57,7 +53,7 @@ class RemotesApiClient {
|
||||
mountBranchName: string;
|
||||
}
|
||||
): Promise<UpsertRemoteResponse> {
|
||||
const response = await fetchWithTimeout(
|
||||
const response = await fetch(
|
||||
`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes`,
|
||||
{
|
||||
method: 'POST',
|
||||
@@ -74,10 +70,6 @@ class RemotesApiClient {
|
||||
}
|
||||
);
|
||||
|
||||
if (!response) {
|
||||
throw new Error(`Failed to upsert.`);
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.getParsedResponse<UpsertRemoteResponse>(response);
|
||||
} catch (err) {
|
||||
@@ -118,7 +110,6 @@ class RemotesApiClient {
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
},
|
||||
body: formData,
|
||||
agent: getProxyAgent(),
|
||||
}
|
||||
);
|
||||
|
||||
@@ -130,7 +121,7 @@ class RemotesApiClient {
|
||||
}
|
||||
|
||||
async getRemotesList(organizationId: string, projectId: string, mountPath: string) {
|
||||
const response = await fetchWithTimeout(
|
||||
const response = await fetch(
|
||||
`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes?filter=mountPath:/${mountPath}/`,
|
||||
{
|
||||
method: 'GET',
|
||||
@@ -141,10 +132,6 @@ class RemotesApiClient {
|
||||
}
|
||||
);
|
||||
|
||||
if (!response) {
|
||||
throw new Error(`Failed to get remotes list.`);
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.getParsedResponse<ListRemotesResponse>(response);
|
||||
} catch (err) {
|
||||
@@ -173,7 +160,7 @@ class RemotesApiClient {
|
||||
);
|
||||
|
||||
if (!response) {
|
||||
throw new Error(`Failed to get push status.`);
|
||||
throw new Error(`Failed to get push status: Time is up`);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
slash,
|
||||
Region,
|
||||
getMergedConfig,
|
||||
getProxyAgent,
|
||||
} from '@redocly/openapi-core';
|
||||
import {
|
||||
exitWithError,
|
||||
@@ -63,12 +62,8 @@ export async function handlePush(argv: PushOptions, config: Config): Promise<voi
|
||||
const client = new RedoclyClient(config.region);
|
||||
const isAuthorized = await client.isAuthorizedWithRedoclyByRegion();
|
||||
if (!isAuthorized) {
|
||||
try {
|
||||
const clientToken = await promptClientToken(client.domain);
|
||||
await client.login(clientToken);
|
||||
} catch (e) {
|
||||
exitWithError(e);
|
||||
}
|
||||
const clientToken = await promptClientToken(client.domain);
|
||||
await client.login(clientToken);
|
||||
}
|
||||
|
||||
const startedAt = performance.now();
|
||||
@@ -444,7 +439,6 @@ function uploadFileToS3(url: string, filePathOrBuffer: string | Buffer) {
|
||||
typeof filePathOrBuffer === 'string'
|
||||
? fs.statSync(filePathOrBuffer).size
|
||||
: filePathOrBuffer.byteLength;
|
||||
|
||||
const readStream =
|
||||
typeof filePathOrBuffer === 'string' ? fs.createReadStream(filePathOrBuffer) : filePathOrBuffer;
|
||||
|
||||
@@ -454,6 +448,5 @@ function uploadFileToS3(url: string, filePathOrBuffer: string | Buffer) {
|
||||
'Content-Length': fileSizeInBytes.toString(),
|
||||
},
|
||||
body: readStream,
|
||||
agent: getProxyAgent(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import nodeFetch from 'node-fetch';
|
||||
import AbortController from 'abort-controller';
|
||||
import { getProxyAgent } from '@redocly/openapi-core';
|
||||
|
||||
const TIMEOUT = 3000;
|
||||
|
||||
@@ -11,11 +10,7 @@ export default async (url: string, options = {}) => {
|
||||
controller.abort();
|
||||
}, TIMEOUT);
|
||||
|
||||
const res = await nodeFetch(url, {
|
||||
signal: controller.signal,
|
||||
...options,
|
||||
agent: getProxyAgent(),
|
||||
});
|
||||
const res = await nodeFetch(url, { signal: controller.signal, ...options });
|
||||
clearTimeout(timeout);
|
||||
return res;
|
||||
} catch (e) {
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
"path": "path-browserify",
|
||||
"os": false,
|
||||
"node-fetch": false,
|
||||
"colorette": false,
|
||||
"https-proxy-agent": false
|
||||
"colorette": false
|
||||
},
|
||||
"homepage": "https://github.com/Redocly/redocly-cli",
|
||||
"keywords": [
|
||||
@@ -37,7 +36,6 @@
|
||||
"dependencies": {
|
||||
"@redocly/ajv": "^8.11.0",
|
||||
"colorette": "^1.2.0",
|
||||
"https-proxy-agent": "^7.0.4",
|
||||
"js-levenshtein": "^1.1.6",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
|
||||
@@ -14,7 +14,7 @@ import { isAbsoluteUrl, isRef, Location, refBaseName } from './ref-utils';
|
||||
import { initRules } from './config/rules';
|
||||
import { reportUnresolvedRef } from './rules/no-unresolved-refs';
|
||||
import { isPlainObject, isTruthy } from './utils';
|
||||
import { isRedoclyRegistryURL } from './redocly/domains';
|
||||
import { isRedoclyRegistryURL } from './redocly';
|
||||
import { RemoveUnusedComponents as RemoveUnusedComponentsOas2 } from './decorators/oas2/remove-unused-components';
|
||||
import { RemoveUnusedComponents as RemoveUnusedComponentsOas3 } from './decorators/oas3/remove-unused-components';
|
||||
import { ConfigTypes } from './types/redocly-yaml';
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
Oas3RuleSet,
|
||||
Async2RuleSet,
|
||||
} from '../oas-types';
|
||||
import { isBrowser } from '../env';
|
||||
import { isBrowser, env } from '../env';
|
||||
|
||||
import type { NodeType } from '../types';
|
||||
import type {
|
||||
@@ -35,6 +35,25 @@ const IGNORE_BANNER =
|
||||
`# This file instructs Redocly's linter to ignore the rules contained for specific parts of your API.\n` +
|
||||
`# See https://redoc.ly/docs/cli/ for more information.\n`;
|
||||
|
||||
export const DEFAULT_REGION = 'us';
|
||||
|
||||
function getDomains() {
|
||||
const domains: { [region in Region]: string } = {
|
||||
us: 'redocly.com',
|
||||
eu: 'eu.redocly.com',
|
||||
};
|
||||
|
||||
// FIXME: temporary fix for our lab environments
|
||||
const domain = env.REDOCLY_DOMAIN;
|
||||
if (domain?.endsWith('.redocly.host')) {
|
||||
domains[domain.split('.')[0] as Region] = domain;
|
||||
}
|
||||
if (domain === 'redoc.online') {
|
||||
domains[domain as Region] = domain;
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
function getIgnoreFilePath(configFile?: string): string | undefined {
|
||||
if (configFile) {
|
||||
return doesYamlFileExist(configFile)
|
||||
@@ -45,6 +64,9 @@ function getIgnoreFilePath(configFile?: string): string | undefined {
|
||||
}
|
||||
}
|
||||
|
||||
export const DOMAINS = getDomains();
|
||||
export const AVAILABLE_REGIONS = Object.keys(DOMAINS) as Region[];
|
||||
|
||||
export class StyleguideConfig {
|
||||
plugins: Plugin[];
|
||||
ignore: Record<string, Record<string, Set<string>>> = {};
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as path from 'path';
|
||||
import { RedoclyClient } from '../redocly';
|
||||
import { isEmptyObject, doesYamlFileExist } from '../utils';
|
||||
import { parseYaml } from '../js-yaml';
|
||||
import { Config } from './config';
|
||||
import { Config, DOMAINS } from './config';
|
||||
import { ConfigValidationError, transformConfig } from './utils';
|
||||
import { resolveConfig, resolveConfigFileAndRefs } from './config-resolvers';
|
||||
import { bundleConfig } from '../bundle';
|
||||
@@ -12,7 +12,6 @@ import type { Document } from '../resolve';
|
||||
import type { RegionalTokenWithValidity } from '../redocly/redocly-client-types';
|
||||
import type { RawConfig, RawUniversalConfig, Region } from './types';
|
||||
import type { BaseResolver, ResolvedRefMap } from '../resolve';
|
||||
import { DOMAINS } from '../redocly/domains';
|
||||
|
||||
async function addConfigMetadata({
|
||||
rawConfig,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UserContext } from '../../walk';
|
||||
import { isRedoclyRegistryURL } from '../../redocly/domains';
|
||||
import { isRedoclyRegistryURL } from '../../redocly';
|
||||
|
||||
import { Oas3Decorator, Oas2Decorator } from '../../visitors';
|
||||
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
export {
|
||||
BundleOutputFormat,
|
||||
readFileFromUrl,
|
||||
slash,
|
||||
doesYamlFileExist,
|
||||
isTruthy,
|
||||
getProxyAgent,
|
||||
} from './utils';
|
||||
export { BundleOutputFormat, readFileFromUrl, slash, doesYamlFileExist, isTruthy } from './utils';
|
||||
export { Oas3_1Types } from './types/oas3_1';
|
||||
export { Oas3Types } from './types/oas3';
|
||||
export { Oas2Types } from './types/oas2';
|
||||
@@ -48,9 +41,7 @@ export {
|
||||
ResolvedApi,
|
||||
} from './config';
|
||||
|
||||
export { RedoclyClient } from './redocly';
|
||||
|
||||
export * from './redocly/domains';
|
||||
export { RedoclyClient, isRedoclyRegistryURL } from './redocly';
|
||||
|
||||
export {
|
||||
Source,
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import { RedoclyClient } from '../../index';
|
||||
import { setRedoclyDomain, getRedoclyDomain, getDomains, AVAILABLE_REGIONS } from '../domains';
|
||||
|
||||
describe('domains', () => {
|
||||
const REDOCLY_DOMAIN_US = 'redocly.com';
|
||||
const TEST_DOMAIN = 'redoclyDomain.com';
|
||||
const TEST_LAB_DOMAIN = 'lab.redocly.host';
|
||||
const TEST_REDOC_ONLINE_DOMAIN = 'redoc.online';
|
||||
|
||||
afterEach(() => {
|
||||
delete process.env.REDOCLY_DOMAIN;
|
||||
setRedoclyDomain('');
|
||||
});
|
||||
|
||||
it('should resolve the US domain by default', () => {
|
||||
expect(getRedoclyDomain()).toBe(REDOCLY_DOMAIN_US);
|
||||
});
|
||||
|
||||
it('should resolve the US and EU regions by default', () => {
|
||||
expect(AVAILABLE_REGIONS).toStrictEqual(['us', 'eu']);
|
||||
});
|
||||
|
||||
it('should resolve the specified domain if used with setter', () => {
|
||||
setRedoclyDomain(TEST_DOMAIN);
|
||||
expect(getRedoclyDomain()).toBe(TEST_DOMAIN);
|
||||
});
|
||||
|
||||
it('should resolve the specified domain provided in environmental variable, after initializing RedoclyClient', () => {
|
||||
process.env.REDOCLY_DOMAIN = TEST_DOMAIN;
|
||||
const client = new RedoclyClient();
|
||||
expect(getRedoclyDomain()).toBe(TEST_DOMAIN);
|
||||
expect(client.domain).toBe(TEST_DOMAIN);
|
||||
});
|
||||
|
||||
it('should return correct object when redocly domain is set to lab env', () => {
|
||||
setRedoclyDomain(TEST_LAB_DOMAIN);
|
||||
const domains = getDomains();
|
||||
expect(domains).toEqual({ us: 'redocly.com', eu: 'eu.redocly.com', lab: 'lab.redocly.host' });
|
||||
expect(getRedoclyDomain()).toBe(TEST_LAB_DOMAIN);
|
||||
});
|
||||
|
||||
it('should return correct object when redocly domain is set to redoc.online env', () => {
|
||||
setRedoclyDomain(TEST_REDOC_ONLINE_DOMAIN);
|
||||
const domains = getDomains();
|
||||
expect(domains).toEqual({
|
||||
us: 'redocly.com',
|
||||
eu: 'eu.redocly.com',
|
||||
'redoc.online': 'redoc.online',
|
||||
});
|
||||
expect(getRedoclyDomain()).toBe(TEST_REDOC_ONLINE_DOMAIN);
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,3 @@
|
||||
import { setRedoclyDomain } from '../domains';
|
||||
import { RedoclyClient } from '../index';
|
||||
|
||||
jest.mock('node-fetch', () => ({
|
||||
@@ -17,7 +16,6 @@ describe('RedoclyClient', () => {
|
||||
|
||||
afterEach(() => {
|
||||
delete process.env.REDOCLY_DOMAIN;
|
||||
setRedoclyDomain('');
|
||||
});
|
||||
|
||||
it('should resolve the US domain by default', () => {
|
||||
@@ -42,19 +40,19 @@ describe('RedoclyClient', () => {
|
||||
});
|
||||
|
||||
it('should resolve domain by EU region prioritizing flag over env variable', () => {
|
||||
setRedoclyDomain(testRedoclyDomain);
|
||||
process.env.REDOCLY_DOMAIN = testRedoclyDomain;
|
||||
const client = new RedoclyClient('eu');
|
||||
expect(client.domain).toBe(REDOCLY_DOMAIN_EU);
|
||||
});
|
||||
|
||||
it('should resolve domain by US region prioritizing flag over env variable', () => {
|
||||
setRedoclyDomain(testRedoclyDomain);
|
||||
process.env.REDOCLY_DOMAIN = testRedoclyDomain;
|
||||
const client = new RedoclyClient('us');
|
||||
expect(client.domain).toBe(REDOCLY_DOMAIN_US);
|
||||
});
|
||||
|
||||
it('should resolve domain by US region when REDOCLY_DOMAIN consists EU domain', () => {
|
||||
setRedoclyDomain(REDOCLY_DOMAIN_EU);
|
||||
process.env.REDOCLY_DOMAIN = REDOCLY_DOMAIN_EU;
|
||||
const client = new RedoclyClient();
|
||||
expect(client.getRegion()).toBe('eu');
|
||||
});
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import { Region } from '../config/types';
|
||||
|
||||
let redoclyDomain = 'redocly.com';
|
||||
|
||||
export const DEFAULT_REGION = 'us';
|
||||
|
||||
export const DOMAINS = getDomains();
|
||||
export const AVAILABLE_REGIONS = Object.keys(DOMAINS) as Region[];
|
||||
|
||||
export function getDomains() {
|
||||
const domains: { [region in Region]: string } = {
|
||||
us: 'redocly.com',
|
||||
eu: 'eu.redocly.com',
|
||||
};
|
||||
|
||||
// FIXME: temporary fix for our lab environments
|
||||
const domain = redoclyDomain;
|
||||
if (domain?.endsWith('.redocly.host')) {
|
||||
domains[domain.split('.')[0] as Region] = domain;
|
||||
}
|
||||
if (domain === 'redoc.online') {
|
||||
domains[domain as Region] = domain;
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
export function setRedoclyDomain(domain: string) {
|
||||
redoclyDomain = domain;
|
||||
}
|
||||
|
||||
export function getRedoclyDomain(): string {
|
||||
return redoclyDomain;
|
||||
}
|
||||
|
||||
export function isRedoclyRegistryURL(link: string): boolean {
|
||||
const domain = getRedoclyDomain() || DOMAINS[DEFAULT_REGION];
|
||||
|
||||
const legacyDomain = domain === 'redocly.com' ? 'redoc.ly' : domain;
|
||||
|
||||
if (
|
||||
!link.startsWith(`https://api.${domain}/registry/`) &&
|
||||
!link.startsWith(`https://api.${legacyDomain}/registry/`)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2,19 +2,13 @@ import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { RegistryApi } from './registry-api';
|
||||
import { DEFAULT_REGION, DOMAINS, AVAILABLE_REGIONS } from '../config/config';
|
||||
import { env } from '../env';
|
||||
import { RegionalToken, RegionalTokenWithValidity } from './redocly-client-types';
|
||||
import { isNotEmptyObject } from '../utils';
|
||||
import { colorize } from '../logger';
|
||||
|
||||
import type { AccessTokens, Region } from '../config/types';
|
||||
import {
|
||||
AVAILABLE_REGIONS,
|
||||
DEFAULT_REGION,
|
||||
DOMAINS,
|
||||
getRedoclyDomain,
|
||||
setRedoclyDomain,
|
||||
} from './domains';
|
||||
|
||||
export const TOKEN_FILENAME = '.redocly-config.json';
|
||||
|
||||
@@ -29,7 +23,7 @@ export class RedoclyClient {
|
||||
this.loadTokens();
|
||||
this.domain = region ? DOMAINS[region] : env.REDOCLY_DOMAIN || DOMAINS[DEFAULT_REGION];
|
||||
|
||||
setRedoclyDomain(this.domain);
|
||||
env.REDOCLY_DOMAIN = this.domain; // isRedoclyRegistryURL depends on the value to be set
|
||||
this.registryApi = new RegistryApi(this.accessTokens, this.region);
|
||||
}
|
||||
|
||||
@@ -42,9 +36,9 @@ export class RedoclyClient {
|
||||
);
|
||||
}
|
||||
|
||||
if (getRedoclyDomain()) {
|
||||
if (env.REDOCLY_DOMAIN) {
|
||||
return (AVAILABLE_REGIONS.find(
|
||||
(region) => DOMAINS[region as Region] === getRedoclyDomain()
|
||||
(region) => DOMAINS[region as Region] === env.REDOCLY_DOMAIN
|
||||
) || DEFAULT_REGION) as Region;
|
||||
}
|
||||
return region || DEFAULT_REGION;
|
||||
@@ -102,7 +96,7 @@ export class RedoclyClient {
|
||||
const allTokens = this.getAllTokens();
|
||||
|
||||
const verifiedTokens = await Promise.allSettled(
|
||||
allTokens.map(({ token }) => this.verifyToken(token))
|
||||
allTokens.map(({ token, region }) => this.verifyToken(token, region))
|
||||
);
|
||||
|
||||
return allTokens
|
||||
@@ -126,7 +120,7 @@ export class RedoclyClient {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.verifyToken(accessToken);
|
||||
await this.verifyToken(accessToken, this.region);
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
@@ -144,16 +138,17 @@ export class RedoclyClient {
|
||||
|
||||
async verifyToken(
|
||||
accessToken: string,
|
||||
region: Region,
|
||||
verbose: boolean = false
|
||||
): Promise<{ viewerId: string; organizations: string[] }> {
|
||||
return this.registryApi.authStatus(accessToken, verbose);
|
||||
return this.registryApi.authStatus(accessToken, region, verbose);
|
||||
}
|
||||
|
||||
async login(accessToken: string, verbose: boolean = false) {
|
||||
const credentialsPath = resolve(homedir(), TOKEN_FILENAME);
|
||||
|
||||
try {
|
||||
await this.verifyToken(accessToken, verbose);
|
||||
await this.verifyToken(accessToken, this.region, verbose);
|
||||
} catch (err) {
|
||||
throw new Error('Authorization failed. Please check if you entered a valid API key.');
|
||||
}
|
||||
@@ -175,3 +170,18 @@ export class RedoclyClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function isRedoclyRegistryURL(link: string): boolean {
|
||||
const domain = env.REDOCLY_DOMAIN || DOMAINS[DEFAULT_REGION];
|
||||
|
||||
const legacyDomain = domain === 'redocly.com' ? 'redoc.ly' : domain;
|
||||
|
||||
if (
|
||||
!link.startsWith(`https://api.${domain}/registry/`) &&
|
||||
!link.startsWith(`https://api.${legacyDomain}/registry/`)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import type {
|
||||
PushApiParams,
|
||||
} from './registry-api-types';
|
||||
import type { AccessTokens, Region } from '../config/types';
|
||||
import { getProxyAgent, isNotEmptyObject } from '../utils';
|
||||
import { getRedoclyDomain } from './domains';
|
||||
import { DEFAULT_REGION, DOMAINS } from '../config/config';
|
||||
import { isNotEmptyObject } from '../utils';
|
||||
|
||||
const version = require('../../package.json').version;
|
||||
|
||||
@@ -18,8 +18,8 @@ export class RegistryApi {
|
||||
return isNotEmptyObject(this.accessTokens) && this.accessTokens[this.region];
|
||||
}
|
||||
|
||||
getBaseUrl() {
|
||||
return `https://api.${getRedoclyDomain()}/registry`;
|
||||
getBaseUrl(region: Region = DEFAULT_REGION) {
|
||||
return `https://api.${DOMAINS[region]}/registry`;
|
||||
}
|
||||
|
||||
setAccessTokens(accessTokens: AccessTokens) {
|
||||
@@ -27,7 +27,7 @@ export class RegistryApi {
|
||||
return this;
|
||||
}
|
||||
|
||||
private async request(path = '', options: RequestInit = {}) {
|
||||
private async request(path = '', options: RequestInit = {}, region?: Region) {
|
||||
const currentCommand =
|
||||
typeof process !== 'undefined' ? process.env?.REDOCLY_CLI_COMMAND || '' : '';
|
||||
const redoclyEnv = typeof process !== 'undefined' ? process.env?.REDOCLY_ENVIRONMENT || '' : '';
|
||||
@@ -42,8 +42,8 @@ export class RegistryApi {
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`${this.getBaseUrl()}${path}`,
|
||||
Object.assign({}, options, { headers, agent: getProxyAgent() })
|
||||
`${this.getBaseUrl(region)}${path}`,
|
||||
Object.assign({}, options, { headers })
|
||||
);
|
||||
|
||||
if (response.status === 401) {
|
||||
@@ -60,10 +60,11 @@ export class RegistryApi {
|
||||
|
||||
async authStatus(
|
||||
accessToken: string,
|
||||
region: Region,
|
||||
verbose = false
|
||||
): Promise<{ viewerId: string; organizations: string[] }> {
|
||||
try {
|
||||
const response = await this.request('', { headers: { authorization: accessToken } });
|
||||
const response = await this.request('', { headers: { authorization: accessToken } }, region);
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
@@ -96,7 +97,8 @@ export class RegistryApi {
|
||||
filename,
|
||||
isUpsert,
|
||||
}),
|
||||
}
|
||||
},
|
||||
this.region
|
||||
);
|
||||
|
||||
if (response.ok) {
|
||||
@@ -118,22 +120,26 @@ export class RegistryApi {
|
||||
batchId,
|
||||
batchSize,
|
||||
}: PushApiParams) {
|
||||
const response = await this.request(`/${organizationId}/${name}/${version}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
authorization: this.accessToken,
|
||||
} as HeadersInit,
|
||||
body: JSON.stringify({
|
||||
rootFilePath,
|
||||
filePaths,
|
||||
branch,
|
||||
isUpsert,
|
||||
isPublic,
|
||||
batchId,
|
||||
batchSize,
|
||||
}),
|
||||
});
|
||||
const response = await this.request(
|
||||
`/${organizationId}/${name}/${version}`,
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
authorization: this.accessToken,
|
||||
} as HeadersInit,
|
||||
body: JSON.stringify({
|
||||
rootFilePath,
|
||||
filePaths,
|
||||
branch,
|
||||
isUpsert,
|
||||
isPublic,
|
||||
batchId,
|
||||
batchSize,
|
||||
}),
|
||||
},
|
||||
this.region
|
||||
);
|
||||
|
||||
if (response.ok) {
|
||||
return;
|
||||
|
||||
@@ -5,10 +5,9 @@ import fetch from 'node-fetch';
|
||||
import * as pluralize from 'pluralize';
|
||||
import { parseYaml } from './js-yaml';
|
||||
import { UserContext } from './walk';
|
||||
import { HttpResolveConfig } from './config';
|
||||
import { env } from './env';
|
||||
import { logger, colorize } from './logger';
|
||||
import { HttpResolveConfig } from './config';
|
||||
import { HttpsProxyAgent } from 'https-proxy-agent';
|
||||
|
||||
export { parseYaml, stringifyYaml } from './js-yaml';
|
||||
|
||||
@@ -275,8 +274,3 @@ export function nextTick() {
|
||||
function getUpdatedFieldName(updatedField: string, updatedObject?: string) {
|
||||
return `${typeof updatedObject !== 'undefined' ? `${updatedObject}.` : ''}${updatedField}`;
|
||||
}
|
||||
|
||||
export function getProxyAgent() {
|
||||
const proxy = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
|
||||
return proxy ? new HttpsProxyAgent(proxy) : undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user