@redocly/cli 1.9.0 → 1.10.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @redocly/cli
2
2
 
3
+ ## 1.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Users can run the CLI tool behind a proxy by using `HTTP_PROXY` or `HTTPS_PROXY` environment variables to configure the proxy settings.
8
+
9
+ ### Patch Changes
10
+
11
+ - Added inflection to the `join` command so that `--prefix-components-with-info-prop` replaces spaces with underscores to create less confusing $refs.
12
+ - Updated @redocly/openapi-core to v1.10.0.
13
+
14
+ ## 1.9.1
15
+
16
+ ### Patch Changes
17
+
18
+ - Adds support for using logical AND for the security schema so that the `join` command generates the correct schema.
19
+ - Fixed a bug with resolving $refs to file names that contain the hash symbol.
20
+ - Fixed a problem where the `join` command did not process schemas containing `null` values when the `--prefix-components-with-info-prop` option was used.'
21
+ - Updated @redocly/openapi-core to v1.9.1.
22
+
3
23
  ## 1.9.0
4
24
 
5
25
  ### Minor Changes
@@ -44,6 +44,7 @@ export declare const loadConfig: jest.Mock<{
44
44
  };
45
45
  }, []>;
46
46
  export declare const getMergedConfig: jest.Mock<any, any>;
47
+ export declare const getProxyAgent: jest.Mock<any, any>;
47
48
  export declare const lint: jest.Mock<any, any>;
48
49
  export declare const bundle: jest.Mock<{
49
50
  bundle: {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Oas3Operations = exports.SpecVersion = exports.YamlParseError = exports.ResolveError = exports.BaseResolver = exports.stringifyYaml = exports.isAbsoluteUrl = exports.detectSpec = exports.bundleDocument = exports.doesYamlFileExist = exports.findConfig = exports.slash = exports.formatProblems = exports.getTotals = exports.bundle = exports.lint = exports.getMergedConfig = exports.loadConfig = exports.RedoclyClient = exports.__redoclyClient = void 0;
3
+ exports.Oas3Operations = exports.SpecVersion = exports.YamlParseError = exports.ResolveError = exports.BaseResolver = exports.stringifyYaml = exports.isAbsoluteUrl = exports.detectSpec = exports.bundleDocument = exports.doesYamlFileExist = exports.findConfig = exports.slash = exports.formatProblems = exports.getTotals = exports.bundle = exports.lint = exports.getProxyAgent = exports.getMergedConfig = exports.loadConfig = exports.RedoclyClient = exports.__redoclyClient = void 0;
4
4
  const config_1 = require("./../../__tests__/fixtures/config");
5
5
  const documents_1 = require("../documents");
6
6
  exports.__redoclyClient = {
@@ -20,6 +20,7 @@ exports.__redoclyClient = {
20
20
  exports.RedoclyClient = jest.fn(() => exports.__redoclyClient);
21
21
  exports.loadConfig = jest.fn(() => config_1.ConfigFixture);
22
22
  exports.getMergedConfig = jest.fn();
23
+ exports.getProxyAgent = jest.fn();
23
24
  exports.lint = jest.fn();
24
25
  exports.bundle = jest.fn(() => ({ bundle: { parsed: null }, problems: null }));
25
26
  exports.getTotals = jest.fn(() => ({ errors: 0 }));
@@ -41,7 +42,8 @@ class BaseResolver {
41
42
  this.resolveDocument = jest
42
43
  .fn()
43
44
  .mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.firstDocument }))
44
- .mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.secondDocument }));
45
+ .mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.secondDocument }))
46
+ .mockImplementationOnce(() => Promise.resolve({ source: { absoluteRef: 'ref' }, parsed: documents_1.thirdDocument }));
45
47
  }
46
48
  }
47
49
  exports.BaseResolver = BaseResolver;
@@ -90,3 +90,61 @@ export declare const secondDocument: {
90
90
  };
91
91
  components: {};
92
92
  };
93
+ export declare const thirdDocument: {
94
+ openapi: string;
95
+ info: {
96
+ title: string;
97
+ version: string;
98
+ };
99
+ servers: {
100
+ url: string;
101
+ }[];
102
+ paths: {};
103
+ components: {
104
+ schemas: {
105
+ SchemaWithNull: {
106
+ type: string;
107
+ default: null;
108
+ nullable: boolean;
109
+ };
110
+ SchemaWithRef: {
111
+ type: string;
112
+ properties: {
113
+ schemaType: {
114
+ type: string;
115
+ enum: string[];
116
+ };
117
+ foo: {
118
+ $ref: string;
119
+ };
120
+ };
121
+ };
122
+ SchemaWithDiscriminator: {
123
+ discriminator: {
124
+ propertyName: string;
125
+ mapping: {
126
+ foo: string;
127
+ bar: string;
128
+ };
129
+ };
130
+ oneOf: ({
131
+ $ref: string;
132
+ type?: undefined;
133
+ properties?: undefined;
134
+ } | {
135
+ type: string;
136
+ properties: {
137
+ schemaType: {
138
+ type: string;
139
+ enum: string[];
140
+ };
141
+ bar: {
142
+ type: string;
143
+ };
144
+ };
145
+ $ref?: undefined;
146
+ })[];
147
+ };
148
+ };
149
+ };
150
+ };
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.secondDocument = exports.firstDocument = void 0;
3
+ exports.thirdDocument = exports.secondDocument = exports.firstDocument = void 0;
4
4
  exports.firstDocument = {
5
5
  openapi: '3.0.0',
6
6
  servers: [{ url: 'http://localhost:8080' }],
7
7
  info: {
8
8
  description: 'example test',
9
9
  version: '1.0.0',
10
- title: 'Swagger Petstore',
10
+ title: 'First API',
11
11
  termsOfService: 'http://swagger.io/terms/',
12
12
  license: {
13
13
  name: 'Apache 2.0',
@@ -37,7 +37,7 @@ exports.secondDocument = {
37
37
  info: {
38
38
  description: 'example test',
39
39
  version: '1.0.0',
40
- title: 'Swagger Petstore',
40
+ title: 'Second API',
41
41
  termsOfService: 'http://swagger.io/terms/',
42
42
  license: {
43
43
  name: 'Apache 2.0',
@@ -61,3 +61,63 @@ exports.secondDocument = {
61
61
  },
62
62
  components: {},
63
63
  };
64
+ exports.thirdDocument = {
65
+ openapi: '3.0.0',
66
+ info: {
67
+ title: 'Third API',
68
+ version: '1.0',
69
+ },
70
+ servers: [
71
+ {
72
+ url: 'https://api.server.test/v1',
73
+ },
74
+ ],
75
+ paths: {},
76
+ components: {
77
+ schemas: {
78
+ SchemaWithNull: {
79
+ type: 'string',
80
+ default: null,
81
+ nullable: true,
82
+ },
83
+ SchemaWithRef: {
84
+ type: 'object',
85
+ properties: {
86
+ schemaType: {
87
+ type: 'string',
88
+ enum: ['foo'],
89
+ },
90
+ foo: {
91
+ $ref: '#/components/schemas/SchemaWithNull',
92
+ },
93
+ },
94
+ },
95
+ SchemaWithDiscriminator: {
96
+ discriminator: {
97
+ propertyName: 'schemaType',
98
+ mapping: {
99
+ foo: '#/components/schemas/SchemaWithRef',
100
+ bar: '#/components/schemas/SchemaWithNull',
101
+ },
102
+ },
103
+ oneOf: [
104
+ {
105
+ $ref: '#/components/schemas/SchemaWithRef',
106
+ },
107
+ {
108
+ type: 'object',
109
+ properties: {
110
+ schemaType: {
111
+ type: 'string',
112
+ enum: ['bar'],
113
+ },
114
+ bar: {
115
+ type: 'string',
116
+ },
117
+ },
118
+ },
119
+ ],
120
+ },
121
+ },
122
+ },
123
+ };
@@ -9,15 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const join_1 = require("../../commands/join");
13
- const miscellaneous_1 = require("../../utils/miscellaneous");
14
12
  const colorette_1 = require("colorette");
15
13
  const openapi_core_1 = require("@redocly/openapi-core");
14
+ const join_1 = require("../../commands/join");
15
+ const miscellaneous_1 = require("../../utils/miscellaneous");
16
16
  const openapi_core_2 = require("../../__mocks__/@redocly/openapi-core");
17
17
  const config_1 = require("../fixtures/config");
18
18
  jest.mock('../../utils/miscellaneous');
19
19
  jest.mock('colorette');
20
- describe('handleJoin fails', () => {
20
+ describe('handleJoin', () => {
21
21
  const colloreteYellowMock = colorette_1.yellow;
22
22
  colloreteYellowMock.mockImplementation((string) => string);
23
23
  it('should call exitWithError because only one entrypoint', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -105,4 +105,127 @@ describe('handleJoin fails', () => {
105
105
  expect(config.styleguide.skipDecorators).not.toHaveBeenCalled();
106
106
  expect(config.styleguide.skipPreprocessors).not.toHaveBeenCalled();
107
107
  }));
108
+ it('should handle join with prefix-components-with-info-prop and null values', () => __awaiter(void 0, void 0, void 0, function* () {
109
+ openapi_core_1.detectSpec.mockReturnValue('oas3_0');
110
+ yield (0, join_1.handleJoin)({
111
+ apis: ['first.yaml', 'second.yaml', 'third.yaml'],
112
+ 'prefix-components-with-info-prop': 'title',
113
+ output: 'join-result.yaml',
114
+ }, config_1.ConfigFixture, 'cli-version');
115
+ expect(miscellaneous_1.writeToFileByExtension).toHaveBeenCalledWith({
116
+ openapi: '3.0.0',
117
+ info: {
118
+ description: 'example test',
119
+ version: '1.0.0',
120
+ title: 'First API',
121
+ termsOfService: 'http://swagger.io/terms/',
122
+ license: {
123
+ name: 'Apache 2.0',
124
+ url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
125
+ },
126
+ },
127
+ servers: [
128
+ {
129
+ url: 'http://localhost:8080',
130
+ },
131
+ {
132
+ url: 'https://api.server.test/v1',
133
+ },
134
+ ],
135
+ tags: [
136
+ {
137
+ name: 'pet',
138
+ 'x-displayName': 'pet',
139
+ },
140
+ ],
141
+ paths: {
142
+ '/GETUser/{userId}': {
143
+ summary: 'get user by id',
144
+ description: 'user info',
145
+ servers: [
146
+ {
147
+ url: '/user',
148
+ },
149
+ {
150
+ url: '/pet',
151
+ description: 'pet server',
152
+ },
153
+ ],
154
+ get: {
155
+ tags: ['pet'],
156
+ summary: 'Find pet by ID',
157
+ description: 'Returns a single pet',
158
+ operationId: 'getPetById',
159
+ servers: [
160
+ {
161
+ url: '/pet',
162
+ },
163
+ ],
164
+ },
165
+ parameters: [
166
+ {
167
+ name: 'param1',
168
+ in: 'header',
169
+ schema: {
170
+ description: 'string',
171
+ },
172
+ },
173
+ ],
174
+ },
175
+ },
176
+ components: {
177
+ schemas: {
178
+ Third_API_SchemaWithNull: {
179
+ type: 'string',
180
+ default: null,
181
+ nullable: true,
182
+ },
183
+ Third_API_SchemaWithRef: {
184
+ type: 'object',
185
+ properties: {
186
+ schemaType: {
187
+ type: 'string',
188
+ enum: ['foo'],
189
+ },
190
+ foo: {
191
+ $ref: '#/components/schemas/Third_API_SchemaWithNull',
192
+ },
193
+ },
194
+ },
195
+ Third_API_SchemaWithDiscriminator: {
196
+ discriminator: {
197
+ propertyName: 'schemaType',
198
+ mapping: {
199
+ foo: '#/components/schemas/Third_API_SchemaWithRef',
200
+ bar: '#/components/schemas/Third_API_SchemaWithNull',
201
+ },
202
+ },
203
+ oneOf: [
204
+ {
205
+ $ref: '#/components/schemas/Third_API_SchemaWithRef',
206
+ },
207
+ {
208
+ type: 'object',
209
+ properties: {
210
+ schemaType: {
211
+ type: 'string',
212
+ enum: ['bar'],
213
+ },
214
+ bar: {
215
+ type: 'string',
216
+ },
217
+ },
218
+ },
219
+ ],
220
+ },
221
+ },
222
+ },
223
+ 'x-tagGroups': [
224
+ {
225
+ name: 'First API',
226
+ tags: ['pet'],
227
+ },
228
+ ],
229
+ }, 'join-result.yaml', true);
230
+ }));
108
231
  });
@@ -42,6 +42,7 @@ describe('ApiClient', () => {
42
42
  'Content-Type': 'application/json',
43
43
  Authorization: `Bearer ${testToken}`,
44
44
  },
45
+ signal: expect.any(Object),
45
46
  });
46
47
  expect(result).toEqual('test-branch');
47
48
  }));
@@ -104,6 +105,8 @@ describe('ApiClient', () => {
104
105
  type: 'CICD',
105
106
  autoMerge: true,
106
107
  }),
108
+ signal: expect.any(Object),
109
+ agent: undefined,
107
110
  });
108
111
  expect(result).toEqual(responseMock);
109
112
  }));
@@ -13,6 +13,7 @@ exports.ReuniteApiClient = void 0;
13
13
  const fetch_with_timeout_1 = require("../../utils/fetch-with-timeout");
14
14
  const node_fetch_1 = require("node-fetch");
15
15
  const FormData = require("form-data");
16
+ const openapi_core_1 = require("@redocly/openapi-core");
16
17
  class RemotesApiClient {
17
18
  constructor(domain, apiKey) {
18
19
  this.domain = domain;
@@ -29,13 +30,16 @@ class RemotesApiClient {
29
30
  }
30
31
  getDefaultBranch(organizationId, projectId) {
31
32
  return __awaiter(this, void 0, void 0, function* () {
32
- const response = yield (0, node_fetch_1.default)(`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/source`, {
33
+ const response = yield (0, fetch_with_timeout_1.default)(`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/source`, {
33
34
  method: 'GET',
34
35
  headers: {
35
36
  'Content-Type': 'application/json',
36
37
  Authorization: `Bearer ${this.apiKey}`,
37
38
  },
38
39
  });
40
+ if (!response) {
41
+ throw new Error(`Failed to get default branch.`);
42
+ }
39
43
  try {
40
44
  const source = yield this.getParsedResponse(response);
41
45
  return source.branchName;
@@ -47,7 +51,7 @@ class RemotesApiClient {
47
51
  }
48
52
  upsert(organizationId, projectId, remote) {
49
53
  return __awaiter(this, void 0, void 0, function* () {
50
- const response = yield (0, node_fetch_1.default)(`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes`, {
54
+ const response = yield (0, fetch_with_timeout_1.default)(`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes`, {
51
55
  method: 'POST',
52
56
  headers: {
53
57
  'Content-Type': 'application/json',
@@ -60,6 +64,9 @@ class RemotesApiClient {
60
64
  autoMerge: true,
61
65
  }),
62
66
  });
67
+ if (!response) {
68
+ throw new Error(`Failed to upsert.`);
69
+ }
63
70
  try {
64
71
  return yield this.getParsedResponse(response);
65
72
  }
@@ -91,6 +98,7 @@ class RemotesApiClient {
91
98
  Authorization: `Bearer ${this.apiKey}`,
92
99
  },
93
100
  body: formData,
101
+ agent: (0, openapi_core_1.getProxyAgent)(),
94
102
  });
95
103
  try {
96
104
  return yield this.getParsedResponse(response);
@@ -102,13 +110,16 @@ class RemotesApiClient {
102
110
  }
103
111
  getRemotesList(organizationId, projectId, mountPath) {
104
112
  return __awaiter(this, void 0, void 0, function* () {
105
- const response = yield (0, node_fetch_1.default)(`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes?filter=mountPath:/${mountPath}/`, {
113
+ const response = yield (0, fetch_with_timeout_1.default)(`${this.domain}/api/orgs/${organizationId}/projects/${projectId}/remotes?filter=mountPath:/${mountPath}/`, {
106
114
  method: 'GET',
107
115
  headers: {
108
116
  'Content-Type': 'application/json',
109
117
  Authorization: `Bearer ${this.apiKey}`,
110
118
  },
111
119
  });
120
+ if (!response) {
121
+ throw new Error(`Failed to get remotes list.`);
122
+ }
112
123
  try {
113
124
  return yield this.getParsedResponse(response);
114
125
  }
@@ -127,7 +138,7 @@ class RemotesApiClient {
127
138
  },
128
139
  });
129
140
  if (!response) {
130
- throw new Error(`Failed to get push status: Time is up`);
141
+ throw new Error(`Failed to get push status.`);
131
142
  }
132
143
  try {
133
144
  return yield this.getParsedResponse(response);
@@ -1,4 +1,5 @@
1
- import { Config, RuleSeverity } from '@redocly/openapi-core';
1
+ import { Config } from '@redocly/openapi-core';
2
+ import type { RuleSeverity } from '@redocly/openapi-core';
2
3
  export type JoinOptions = {
3
4
  apis: string[];
4
5
  lint?: boolean;
@@ -18,7 +18,7 @@ const openapi_core_1 = require("@redocly/openapi-core");
18
18
  const miscellaneous_1 = require("../utils/miscellaneous");
19
19
  const js_utils_1 = require("../utils/js-utils");
20
20
  const types_1 = require("./split/types");
21
- const COMPONENTS = 'components';
21
+ const split_1 = require("./split");
22
22
  const Tags = 'tags';
23
23
  const xTagGroups = 'x-tagGroups';
24
24
  let potentialConflictsTotal = 0;
@@ -112,7 +112,7 @@ function handleJoin(argv, config, packageVersion) {
112
112
  const tagsPrefix = prefixTagsWithFilename
113
113
  ? apiFilename
114
114
  : getInfoPrefix(info, prefixTagsWithInfoProp, 'tags');
115
- const componentsPrefix = getInfoPrefix(info, prefixComponentsWithInfoProp, COMPONENTS);
115
+ const componentsPrefix = getInfoPrefix(info, prefixComponentsWithInfoProp, types_1.COMPONENTS);
116
116
  if (openapi.hasOwnProperty('x-tagGroups')) {
117
117
  process.stderr.write((0, colorette_1.yellow)(`warning: x-tagGroups at ${(0, colorette_1.blue)(api)} will be skipped \n`));
118
118
  }
@@ -390,13 +390,13 @@ function handleJoin(argv, config, packageVersion) {
390
390
  function collectComponents(openapi, { api, potentialConflicts, componentsPrefix }) {
391
391
  const { components } = openapi;
392
392
  if (components) {
393
- if (!joinedDef.hasOwnProperty(COMPONENTS)) {
394
- joinedDef[COMPONENTS] = {};
393
+ if (!joinedDef.hasOwnProperty(types_1.COMPONENTS)) {
394
+ joinedDef[types_1.COMPONENTS] = {};
395
395
  }
396
396
  for (const [component, componentObj] of Object.entries(components)) {
397
- if (!potentialConflicts[COMPONENTS].hasOwnProperty(component)) {
398
- potentialConflicts[COMPONENTS][component] = {};
399
- joinedDef[COMPONENTS][component] = {};
397
+ if (!potentialConflicts[types_1.COMPONENTS].hasOwnProperty(component)) {
398
+ potentialConflicts[types_1.COMPONENTS][component] = {};
399
+ joinedDef[types_1.COMPONENTS][component] = {};
400
400
  }
401
401
  for (const item of Object.keys(componentObj)) {
402
402
  const componentPrefix = addPrefix(item, componentsPrefix);
@@ -449,7 +449,7 @@ function handleJoin(argv, config, packageVersion) {
449
449
  var _a;
450
450
  const firstApi = documents[0];
451
451
  const openapi = firstApi.parsed;
452
- const componentsPrefix = getInfoPrefix(openapi.info, prefixComponentsWithInfoProp, COMPONENTS);
452
+ const componentsPrefix = getInfoPrefix(openapi.info, prefixComponentsWithInfoProp, types_1.COMPONENTS);
453
453
  if (!openapi.openapi)
454
454
  (0, miscellaneous_1.exitWithError)('Version of specification is not found in. \n');
455
455
  if (!openapi.info)
@@ -481,7 +481,7 @@ function iteratePotentialConflicts(potentialConflicts, withoutXTagGroups) {
481
481
  for (const [key, value] of Object.entries(potentialConflicts[group])) {
482
482
  const conflicts = filterConflicts(value);
483
483
  if (conflicts.length) {
484
- if (group === COMPONENTS) {
484
+ if (group === types_1.COMPONENTS) {
485
485
  for (const [_, conflict] of Object.entries(conflicts)) {
486
486
  if (validateComponentsDifference(conflict[1])) {
487
487
  conflict[1] = conflict[1].map((c) => Object.keys(c)[0]);
@@ -540,8 +540,11 @@ function addComponentsPrefix(description, componentsPrefix) {
540
540
  function addSecurityPrefix(security, componentsPrefix) {
541
541
  return componentsPrefix
542
542
  ? security === null || security === void 0 ? void 0 : security.map((s) => {
543
- const key = Object.keys(s)[0];
544
- return { [componentsPrefix + '_' + key]: s[key] };
543
+ const joinedSecuritySchema = {};
544
+ for (const [key, value] of Object.entries(s)) {
545
+ Object.assign(joinedSecuritySchema, { [componentsPrefix + '_' + key]: value });
546
+ }
547
+ return joinedSecuritySchema;
545
548
  })
546
549
  : security;
547
550
  }
@@ -556,7 +559,7 @@ function getInfoPrefix(info, prefixArg, type) {
556
559
  (0, miscellaneous_1.exitWithError)(`${(0, colorette_1.yellow)(`prefix-${type}-with-info-prop`)} argument value should be string. \n\n`);
557
560
  if (info[prefixArg].length > 50)
558
561
  (0, miscellaneous_1.exitWithError)(`${(0, colorette_1.yellow)(`prefix-${type}-with-info-prop`)} argument value length should not exceed 50 characters. \n\n`);
559
- return info[prefixArg];
562
+ return info[prefixArg].replaceAll(/\s/g, '_');
560
563
  }
561
564
  function validateApi(document, config, externalRefResolver, packageVersion) {
562
565
  return __awaiter(this, void 0, void 0, function* () {
@@ -571,27 +574,18 @@ function validateApi(document, config, externalRefResolver, packageVersion) {
571
574
  }
572
575
  });
573
576
  }
574
- function crawl(object, visitor) {
575
- if (!(0, js_utils_1.isObject)(object))
576
- return;
577
- for (const key of Object.keys(object)) {
578
- visitor(object[key], key);
579
- crawl(object[key], visitor);
580
- }
581
- }
582
577
  function replace$Refs(obj, componentsPrefix) {
583
- crawl(obj, (node) => {
584
- if (node.$ref && (0, js_utils_1.isString)(node.$ref) && node.$ref.startsWith(`#/${COMPONENTS}/`)) {
578
+ (0, split_1.crawl)(obj, (node) => {
579
+ if (node.$ref && typeof node.$ref === 'string' && (0, split_1.startsWithComponents)(node.$ref)) {
585
580
  const name = path.basename(node.$ref);
586
581
  node.$ref = node.$ref.replace(name, componentsPrefix + '_' + name);
587
582
  }
588
- else if (node.discriminator &&
589
- node.discriminator.mapping &&
590
- (0, js_utils_1.isObject)(node.discriminator.mapping)) {
583
+ else if ((0, js_utils_1.isObject)(node.discriminator) && (0, js_utils_1.isObject)(node.discriminator.mapping)) {
591
584
  const { mapping } = node.discriminator;
592
585
  for (const name of Object.keys(mapping)) {
593
- if ((0, js_utils_1.isString)(mapping[name]) && mapping[name].startsWith(`#/${COMPONENTS}/`)) {
594
- mapping[name] = mapping[name]
586
+ const mappingPointer = mapping[name];
587
+ if (typeof mappingPointer === 'string' && (0, split_1.startsWithComponents)(mappingPointer)) {
588
+ mapping[name] = mappingPointer
595
589
  .split('/')
596
590
  .map((name, i, arr) => {
597
591
  return arr.length - 1 === i && !name.includes(componentsPrefix)
@@ -45,8 +45,13 @@ function handlePush(argv, config) {
45
45
  const client = new openapi_core_1.RedoclyClient(config.region);
46
46
  const isAuthorized = yield client.isAuthorizedWithRedoclyByRegion();
47
47
  if (!isAuthorized) {
48
- const clientToken = yield (0, login_1.promptClientToken)(client.domain);
49
- yield client.login(clientToken);
48
+ try {
49
+ const clientToken = yield (0, login_1.promptClientToken)(client.domain);
50
+ yield client.login(clientToken);
51
+ }
52
+ catch (e) {
53
+ (0, miscellaneous_1.exitWithError)(e);
54
+ }
50
55
  }
51
56
  const startedAt = perf_hooks_1.performance.now();
52
57
  const { destination, branchName, upsert } = argv;
@@ -300,5 +305,6 @@ function uploadFileToS3(url, filePathOrBuffer) {
300
305
  'Content-Length': fileSizeInBytes.toString(),
301
306
  },
302
307
  body: readStream,
308
+ agent: (0, openapi_core_1.getProxyAgent)(),
303
309
  });
304
310
  }
@@ -1,4 +1,4 @@
1
- import { Oas3PathItem, Referenced } from './types';
1
+ import type { Oas3PathItem, Referenced } from './types';
2
2
  export type SplitOptions = {
3
3
  api: string;
4
4
  outDir: string;
@@ -6,5 +6,7 @@ export type SplitOptions = {
6
6
  config?: string;
7
7
  };
8
8
  export declare function handleSplit(argv: SplitOptions): Promise<void>;
9
+ export declare function startsWithComponents(node: string): boolean;
10
+ export declare function crawl(object: unknown, visitor: (node: Record<string, unknown>) => void): void;
9
11
  declare function iteratePathItems(pathItems: Record<string, Referenced<Oas3PathItem>> | undefined, openapiDir: string, outDir: string, componentsFiles: object, pathSeparator: string, codeSamplesPathPrefix: string | undefined, ext: string): void;
10
12
  export { iteratePathItems };
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.iteratePathItems = exports.handleSplit = void 0;
12
+ exports.iteratePathItems = exports.crawl = exports.startsWithComponents = exports.handleSplit = void 0;
13
13
  const colorette_1 = require("colorette");
14
14
  const fs = require("fs");
15
15
  const openapi_core_1 = require("@redocly/openapi-core");
@@ -44,9 +44,10 @@ function splitDefinition(openapi, openapiDir, pathSeparator, ext) {
44
44
  replace$Refs(openapi, openapiDir, componentsFiles);
45
45
  (0, miscellaneous_1.writeToFileByExtension)(openapi, path.join(openapiDir, `openapi.${ext}`));
46
46
  }
47
- function isStartsWithComponents(node) {
48
- return node.startsWith(types_1.componentsPath);
47
+ function startsWithComponents(node) {
48
+ return node.startsWith(`#/${types_1.COMPONENTS}/`);
49
49
  }
50
+ exports.startsWithComponents = startsWithComponents;
50
51
  function isSupportedExtension(filename) {
51
52
  return filename.endsWith('.yaml') || filename.endsWith('.yml') || filename.endsWith('.json');
52
53
  }
@@ -92,22 +93,22 @@ function traverseDirectoryDeepCallback(filename, directory, componentsFiles) {
92
93
  function crawl(object, visitor) {
93
94
  if (!(0, js_utils_1.isObject)(object))
94
95
  return;
96
+ visitor(object);
95
97
  for (const key of Object.keys(object)) {
96
- visitor(object, key);
97
98
  crawl(object[key], visitor);
98
99
  }
99
100
  }
101
+ exports.crawl = crawl;
100
102
  function replace$Refs(obj, relativeFrom, componentFiles = {}) {
101
103
  crawl(obj, (node) => {
102
- if (node.$ref && (0, js_utils_1.isString)(node.$ref) && isStartsWithComponents(node.$ref)) {
104
+ if (node.$ref && typeof node.$ref === 'string' && startsWithComponents(node.$ref)) {
103
105
  replace(node, '$ref');
104
106
  }
105
- else if (node.discriminator &&
106
- node.discriminator.mapping &&
107
- (0, js_utils_1.isObject)(node.discriminator.mapping)) {
107
+ else if ((0, js_utils_1.isObject)(node.discriminator) && (0, js_utils_1.isObject)(node.discriminator.mapping)) {
108
108
  const { mapping } = node.discriminator;
109
109
  for (const name of Object.keys(mapping)) {
110
- if ((0, js_utils_1.isString)(mapping[name]) && isStartsWithComponents(mapping[name])) {
110
+ const mappingPointer = mapping[name];
111
+ if (typeof mappingPointer === 'string' && startsWithComponents(mappingPointer)) {
111
112
  replace(node.discriminator.mapping, name);
112
113
  }
113
114
  }