@redocly/cli 1.18.1 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/lib/__mocks__/@redocly/openapi-core.d.ts +2 -2
  3. package/lib/__mocks__/@redocly/openapi-core.js +1 -0
  4. package/lib/__mocks__/fs.d.ts +0 -1
  5. package/lib/__mocks__/perf_hooks.d.ts +0 -1
  6. package/lib/__mocks__/redoc.d.ts +0 -1
  7. package/lib/__tests__/commands/build-docs.test.js +21 -23
  8. package/lib/__tests__/commands/bundle.test.js +21 -30
  9. package/lib/__tests__/commands/join.test.js +101 -70
  10. package/lib/__tests__/commands/lint.test.js +54 -54
  11. package/lib/__tests__/commands/push-region.test.js +24 -25
  12. package/lib/__tests__/commands/push.test.js +269 -170
  13. package/lib/__tests__/fetch-with-timeout.test.js +3 -12
  14. package/lib/__tests__/fixtures/config.d.ts +0 -1
  15. package/lib/__tests__/utils.test.js +32 -37
  16. package/lib/__tests__/wrapper.test.js +31 -20
  17. package/lib/cms/api/__tests__/api.client.test.js +29 -38
  18. package/lib/cms/api/api-client.d.ts +0 -2
  19. package/lib/cms/api/api-client.js +106 -127
  20. package/lib/cms/api/api-keys.js +1 -2
  21. package/lib/cms/api/domains.js +1 -2
  22. package/lib/cms/commands/__tests__/push-status.test.js +251 -162
  23. package/lib/cms/commands/__tests__/push.test.js +120 -102
  24. package/lib/cms/commands/__tests__/utils.test.js +12 -21
  25. package/lib/cms/commands/push-status.d.ts +3 -2
  26. package/lib/cms/commands/push-status.js +94 -106
  27. package/lib/cms/commands/push.d.ts +3 -2
  28. package/lib/cms/commands/push.js +66 -74
  29. package/lib/cms/commands/utils.js +20 -34
  30. package/lib/commands/build-docs/index.d.ts +2 -2
  31. package/lib/commands/build-docs/index.js +8 -17
  32. package/lib/commands/build-docs/utils.js +26 -38
  33. package/lib/commands/bundle.d.ts +2 -2
  34. package/lib/commands/bundle.js +70 -94
  35. package/lib/commands/join.d.ts +2 -2
  36. package/lib/commands/join.js +375 -388
  37. package/lib/commands/lint.d.ts +2 -2
  38. package/lib/commands/lint.js +64 -75
  39. package/lib/commands/login.d.ts +3 -2
  40. package/lib/commands/login.js +9 -21
  41. package/lib/commands/preview-docs/index.d.ts +2 -2
  42. package/lib/commands/preview-docs/index.js +92 -106
  43. package/lib/commands/preview-docs/preview-server/preview-server.js +64 -76
  44. package/lib/commands/preview-docs/preview-server/server.d.ts +0 -3
  45. package/lib/commands/preview-docs/preview-server/server.js +6 -6
  46. package/lib/commands/preview-project/index.d.ts +2 -1
  47. package/lib/commands/preview-project/index.js +5 -14
  48. package/lib/commands/push.d.ts +8 -11
  49. package/lib/commands/push.js +177 -195
  50. package/lib/commands/split/__tests__/index.test.js +31 -25
  51. package/lib/commands/split/index.d.ts +2 -1
  52. package/lib/commands/split/index.js +20 -33
  53. package/lib/commands/stats.d.ts +2 -2
  54. package/lib/commands/stats.js +34 -45
  55. package/lib/index.js +32 -46
  56. package/lib/types.d.ts +2 -2
  57. package/lib/utils/__mocks__/miscellaneous.d.ts +0 -1
  58. package/lib/utils/fetch-with-timeout.js +7 -12
  59. package/lib/utils/getCommandNameFromArgs.js +2 -4
  60. package/lib/utils/js-utils.js +6 -7
  61. package/lib/utils/miscellaneous.d.ts +4 -1
  62. package/lib/utils/miscellaneous.js +130 -152
  63. package/lib/utils/update-version-notifier.js +4 -13
  64. package/lib/wrapper.d.ts +9 -2
  65. package/lib/wrapper.js +27 -16
  66. package/package.json +3 -3
  67. package/src/__mocks__/@redocly/openapi-core.ts +1 -0
  68. package/src/__tests__/commands/build-docs.test.ts +5 -4
  69. package/src/__tests__/commands/join.test.ts +51 -51
  70. package/src/__tests__/commands/push-region.test.ts +10 -8
  71. package/src/__tests__/commands/push.test.ts +127 -102
  72. package/src/__tests__/utils.test.ts +1 -0
  73. package/src/__tests__/wrapper.test.ts +24 -2
  74. package/src/cms/commands/__tests__/push-status.test.ts +70 -56
  75. package/src/cms/commands/__tests__/push.test.ts +30 -24
  76. package/src/cms/commands/push-status.ts +8 -7
  77. package/src/cms/commands/push.ts +12 -9
  78. package/src/commands/build-docs/index.ts +10 -5
  79. package/src/commands/bundle.ts +14 -6
  80. package/src/commands/join.ts +6 -2
  81. package/src/commands/lint.ts +9 -3
  82. package/src/commands/login.ts +4 -2
  83. package/src/commands/preview-docs/index.ts +6 -1
  84. package/src/commands/preview-project/index.ts +5 -4
  85. package/src/commands/push.ts +13 -15
  86. package/src/commands/split/__tests__/index.test.ts +17 -6
  87. package/src/commands/split/index.ts +4 -2
  88. package/src/commands/stats.ts +4 -2
  89. package/src/utils/miscellaneous.ts +11 -1
  90. package/src/wrapper.ts +37 -11
  91. package/tsconfig.tsbuildinfo +1 -1
@@ -1,6 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
- /// <reference types="node" />
4
1
  import * as http from 'http';
5
2
  import { ReadStream } from 'fs';
6
3
  export declare const mimeTypes: {
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.startWsServer = exports.startHttpServer = exports.respondWithGzip = exports.mimeTypes = void 0;
3
+ exports.mimeTypes = void 0;
4
+ exports.respondWithGzip = respondWithGzip;
5
+ exports.startHttpServer = startHttpServer;
6
+ exports.startWsServer = startWsServer;
4
7
  const http = require("http");
5
8
  const zlib = require("zlib");
6
9
  const SocketServer = require('simple-websocket/server.js');
@@ -26,11 +29,11 @@ function respondWithGzip(contents, request, response, headers = {}, code = 200)
26
29
  let compressedStream;
27
30
  const acceptEncoding = request.headers['accept-encoding'] || '';
28
31
  if (acceptEncoding.match(/\bdeflate\b/)) {
29
- response.writeHead(code, Object.assign(Object.assign({}, headers), { 'content-encoding': 'deflate' }));
32
+ response.writeHead(code, { ...headers, 'content-encoding': 'deflate' });
30
33
  compressedStream = zlib.createDeflate();
31
34
  }
32
35
  else if (acceptEncoding.match(/\bgzip\b/)) {
33
- response.writeHead(code, Object.assign(Object.assign({}, headers), { 'content-encoding': 'gzip' }));
36
+ response.writeHead(code, { ...headers, 'content-encoding': 'gzip' });
34
37
  compressedStream = zlib.createGzip();
35
38
  }
36
39
  else {
@@ -53,11 +56,9 @@ function respondWithGzip(contents, request, response, headers = {}, code = 200)
53
56
  contents.pipe(compressedStream).pipe(response);
54
57
  }
55
58
  }
56
- exports.respondWithGzip = respondWithGzip;
57
59
  function startHttpServer(port, host, handler) {
58
60
  return http.createServer(handler).listen(port, host);
59
61
  }
60
- exports.startHttpServer = startHttpServer;
61
62
  function startWsServer(port, host) {
62
63
  const socketServer = new SocketServer({ port, host, clientTracking: true });
63
64
  socketServer.on('connection', (socket) => {
@@ -82,4 +83,3 @@ function startWsServer(port, host) {
82
83
  };
83
84
  return socketServer;
84
85
  }
85
- exports.startWsServer = startWsServer;
@@ -1,2 +1,3 @@
1
1
  import type { PreviewProjectOptions } from './types';
2
- export declare const previewProject: (args: PreviewProjectOptions) => Promise<void>;
2
+ import type { CommandArgs } from '../../wrapper';
3
+ export declare const previewProject: ({ argv }: CommandArgs<PreviewProjectOptions>) => Promise<void>;
@@ -1,23 +1,14 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.previewProject = void 0;
13
4
  const path = require("path");
14
5
  const fs_1 = require("fs");
15
6
  const child_process_1 = require("child_process");
16
7
  const constants_1 = require("./constants");
17
- const previewProject = (args) => __awaiter(void 0, void 0, void 0, function* () {
18
- const { plan, port } = args;
19
- const projectDir = args['source-dir'];
20
- const product = args.product || tryGetProductFromPackageJson(projectDir);
8
+ const previewProject = async ({ argv }) => {
9
+ const { plan, port } = argv;
10
+ const projectDir = argv['source-dir'];
11
+ const product = argv.product || tryGetProductFromPackageJson(projectDir);
21
12
  if (!isValidProduct(product)) {
22
13
  process.stderr.write(`Invalid product ${product}`);
23
14
  throw new Error(`Project preview launch failed`);
@@ -30,7 +21,7 @@ const previewProject = (args) => __awaiter(void 0, void 0, void 0, function* ()
30
21
  stdio: 'inherit',
31
22
  cwd: projectDir,
32
23
  });
33
- });
24
+ };
34
25
  exports.previewProject = previewProject;
35
26
  const isValidProduct = (product) => {
36
27
  if (!product) {
@@ -1,5 +1,6 @@
1
1
  import { Config, Region } from '@redocly/openapi-core';
2
2
  import { handlePush as handleCMSPush } from '../cms/commands/push';
3
+ import type { CommandArgs } from '../wrapper';
3
4
  export declare const DESTINATION_REGEX: RegExp;
4
5
  export type PushOptions = {
5
6
  api?: string;
@@ -18,14 +19,10 @@ export type PushOptions = {
18
19
  export declare function commonPushHandler({ project, 'mount-path': mountPath, }: {
19
20
  project?: string;
20
21
  'mount-path'?: string;
21
- }): typeof handleCMSPush | (({ apis, branch, "batch-id": batchId, "job-id": jobId, ...rest }: Omit<PushOptions, "destination" | "branchName"> & {
22
- apis?: string[] | undefined;
23
- branch?: string | undefined;
24
- destination?: string | undefined;
25
- } & {
26
- 'batch-id'?: string | undefined;
27
- }, config: Config) => Promise<void>);
28
- export declare function handlePush(argv: PushOptions, config: Config): Promise<void>;
22
+ }): typeof handleCMSPush | (({ argv: { apis, branch, "batch-id": batchId, "job-id": jobId, ...rest }, config, version, }: CommandArgs<BarePushArgs & {
23
+ "batch-id"?: string;
24
+ }>) => Promise<void>);
25
+ export declare function handlePush({ argv, config }: CommandArgs<PushOptions>): Promise<void>;
29
26
  export declare function getDestinationProps(destination: string | undefined, organization: string | undefined): {
30
27
  organizationId: string | undefined;
31
28
  name: string | undefined;
@@ -36,9 +33,9 @@ type BarePushArgs = Omit<PushOptions, 'destination' | 'branchName'> & {
36
33
  branch?: string;
37
34
  destination?: string;
38
35
  };
39
- export declare const transformPush: (callback: typeof handlePush) => ({ apis, branch, "batch-id": batchId, "job-id": jobId, ...rest }: BarePushArgs & {
40
- 'batch-id'?: string;
41
- }, config: Config) => Promise<void>;
36
+ export declare const transformPush: (callback: typeof handlePush) => ({ argv: { apis, branch, "batch-id": batchId, "job-id": jobId, ...rest }, config, version, }: CommandArgs<BarePushArgs & {
37
+ "batch-id"?: string;
38
+ }>) => Promise<void>;
42
39
  export declare function getApiRoot({ name, version, config: { apis }, }: {
43
40
  name: string;
44
41
  version: string;
@@ -1,26 +1,10 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __rest = (this && this.__rest) || function (s, e) {
12
- var t = {};
13
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
- t[p] = s[p];
15
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
- t[p[i]] = s[p[i]];
19
- }
20
- return t;
21
- };
22
2
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.getApiRoot = exports.transformPush = exports.getDestinationProps = exports.handlePush = exports.commonPushHandler = exports.DESTINATION_REGEX = void 0;
3
+ exports.transformPush = exports.DESTINATION_REGEX = void 0;
4
+ exports.commonPushHandler = commonPushHandler;
5
+ exports.handlePush = handlePush;
6
+ exports.getDestinationProps = getDestinationProps;
7
+ exports.getApiRoot = getApiRoot;
24
8
  const fs = require("fs");
25
9
  const path = require("path");
26
10
  const node_fetch_1 = require("node-fetch");
@@ -39,113 +23,109 @@ function commonPushHandler({ project, 'mount-path': mountPath, }) {
39
23
  }
40
24
  return (0, exports.transformPush)(handlePush);
41
25
  }
42
- exports.commonPushHandler = commonPushHandler;
43
- function handlePush(argv, config) {
44
- return __awaiter(this, void 0, void 0, function* () {
45
- const client = new openapi_core_1.RedoclyClient(config.region);
46
- const isAuthorized = yield client.isAuthorizedWithRedoclyByRegion();
47
- if (!isAuthorized) {
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
- }
55
- }
56
- const startedAt = perf_hooks_1.performance.now();
57
- const { destination, branchName, upsert } = argv;
58
- const jobId = argv['job-id'];
59
- const batchSize = argv['batch-size'];
60
- if (destination && !exports.DESTINATION_REGEX.test(destination)) {
61
- (0, miscellaneous_1.exitWithError)(`Destination argument value is not valid, please use the right format: ${(0, colorette_1.yellow)('<api-name@api-version>')}.`);
62
- }
63
- const destinationProps = getDestinationProps(destination, config.organization);
64
- const organizationId = argv.organization || destinationProps.organizationId;
65
- const { name, version } = destinationProps;
66
- if (!organizationId) {
67
- return (0, miscellaneous_1.exitWithError)(`No organization provided, please use --organization option or specify the 'organization' field in the config file.`);
68
- }
69
- const api = argv.api || (name && version && getApiRoot({ name, version, config }));
70
- if (name && version && !api) {
71
- (0, miscellaneous_1.exitWithError)(`No api found that matches ${(0, colorette_1.blue)(`${name}@${version}`)}. Please make sure you have provided the correct data in the config file.`);
72
- }
73
- // Ensure that a destination for the api is provided.
74
- if (!name && api) {
75
- return (0, miscellaneous_1.exitWithError)(`No destination provided, please use --destination option to provide destination.`);
76
- }
77
- if (jobId && !jobId.trim()) {
78
- (0, miscellaneous_1.exitWithError)(`The ${(0, colorette_1.blue)(`job-id`)} option value is not valid, please avoid using an empty string.`);
26
+ async function handlePush({ argv, config }) {
27
+ const client = new openapi_core_1.RedoclyClient(config.region);
28
+ const isAuthorized = await client.isAuthorizedWithRedoclyByRegion();
29
+ if (!isAuthorized) {
30
+ try {
31
+ const clientToken = await (0, login_1.promptClientToken)(client.domain);
32
+ await client.login(clientToken);
79
33
  }
80
- if (batchSize && batchSize < 2) {
81
- (0, miscellaneous_1.exitWithError)(`The ${(0, colorette_1.blue)(`batch-size`)} option value is not valid, please use the integer bigger than 1.`);
34
+ catch (e) {
35
+ (0, miscellaneous_1.exitWithError)(e);
82
36
  }
83
- const apis = api ? { [`${name}@${version}`]: { root: api } } : config.apis;
84
- if (!Object.keys(apis).length) {
85
- (0, miscellaneous_1.exitWithError)(`Api not found. Please make sure you have provided the correct data in the config file.`);
86
- }
87
- for (const [apiNameAndVersion, { root: api }] of Object.entries(apis)) {
88
- const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, apiNameAndVersion);
89
- resolvedConfig.styleguide.skipDecorators(argv['skip-decorator']);
90
- const [name, version = DEFAULT_VERSION] = apiNameAndVersion.split('@');
91
- const encodedName = encodeURIComponent(name);
92
- try {
93
- let rootFilePath = '';
94
- const filePaths = [];
95
- const filesToUpload = yield collectFilesToUpload(api, resolvedConfig);
96
- const filesHash = hashFiles(filesToUpload.files);
97
- process.stdout.write(`Uploading ${filesToUpload.files.length} ${(0, miscellaneous_1.pluralize)('file', filesToUpload.files.length)}:\n`);
98
- let uploaded = 0;
99
- for (const file of filesToUpload.files) {
100
- const { signedUploadUrl, filePath } = yield client.registryApi.prepareFileUpload({
101
- organizationId,
102
- name: encodedName,
103
- version,
104
- filesHash,
105
- filename: file.keyOnS3,
106
- isUpsert: upsert,
107
- });
108
- if (file.filePath === filesToUpload.root) {
109
- rootFilePath = filePath;
110
- }
111
- filePaths.push(filePath);
112
- process.stdout.write(`Uploading ${file.contents ? 'bundle for ' : ''}${(0, colorette_1.blue)(file.filePath)}...`);
113
- const uploadResponse = yield uploadFileToS3(signedUploadUrl, file.contents || file.filePath);
114
- const fileCounter = `(${++uploaded}/${filesToUpload.files.length})`;
115
- if (!uploadResponse.ok) {
116
- (0, miscellaneous_1.exitWithError)(`✗ ${fileCounter}\nFile upload failed.`);
117
- }
118
- process.stdout.write((0, colorette_1.green)(`✓ ${fileCounter}\n`));
119
- }
120
- process.stdout.write('\n');
121
- yield client.registryApi.pushApi({
37
+ }
38
+ const startedAt = perf_hooks_1.performance.now();
39
+ const { destination, branchName, upsert } = argv;
40
+ const jobId = argv['job-id'];
41
+ const batchSize = argv['batch-size'];
42
+ if (destination && !exports.DESTINATION_REGEX.test(destination)) {
43
+ (0, miscellaneous_1.exitWithError)(`Destination argument value is not valid, please use the right format: ${(0, colorette_1.yellow)('<api-name@api-version>')}.`);
44
+ }
45
+ const destinationProps = getDestinationProps(destination, config.organization);
46
+ const organizationId = argv.organization || destinationProps.organizationId;
47
+ const { name, version } = destinationProps;
48
+ if (!organizationId) {
49
+ return (0, miscellaneous_1.exitWithError)(`No organization provided, please use --organization option or specify the 'organization' field in the config file.`);
50
+ }
51
+ const api = argv.api || (name && version && getApiRoot({ name, version, config }));
52
+ if (name && version && !api) {
53
+ (0, miscellaneous_1.exitWithError)(`No api found that matches ${(0, colorette_1.blue)(`${name}@${version}`)}. Please make sure you have provided the correct data in the config file.`);
54
+ }
55
+ // Ensure that a destination for the api is provided.
56
+ if (!name && api) {
57
+ return (0, miscellaneous_1.exitWithError)(`No destination provided, please use --destination option to provide destination.`);
58
+ }
59
+ if (jobId && !jobId.trim()) {
60
+ (0, miscellaneous_1.exitWithError)(`The ${(0, colorette_1.blue)(`job-id`)} option value is not valid, please avoid using an empty string.`);
61
+ }
62
+ if (batchSize && batchSize < 2) {
63
+ (0, miscellaneous_1.exitWithError)(`The ${(0, colorette_1.blue)(`batch-size`)} option value is not valid, please use the integer bigger than 1.`);
64
+ }
65
+ const apis = api ? { [`${name}@${version}`]: { root: api } } : config.apis;
66
+ if (!Object.keys(apis).length) {
67
+ (0, miscellaneous_1.exitWithError)(`Api not found. Please make sure you have provided the correct data in the config file.`);
68
+ }
69
+ for (const [apiNameAndVersion, { root: api }] of Object.entries(apis)) {
70
+ const resolvedConfig = (0, openapi_core_1.getMergedConfig)(config, apiNameAndVersion);
71
+ resolvedConfig.styleguide.skipDecorators(argv['skip-decorator']);
72
+ const [name, version = DEFAULT_VERSION] = apiNameAndVersion.split('@');
73
+ const encodedName = encodeURIComponent(name);
74
+ try {
75
+ let rootFilePath = '';
76
+ const filePaths = [];
77
+ const filesToUpload = await collectFilesToUpload(api, resolvedConfig);
78
+ const filesHash = hashFiles(filesToUpload.files);
79
+ process.stdout.write(`Uploading ${filesToUpload.files.length} ${(0, miscellaneous_1.pluralize)('file', filesToUpload.files.length)}:\n`);
80
+ let uploaded = 0;
81
+ for (const file of filesToUpload.files) {
82
+ const { signedUploadUrl, filePath } = await client.registryApi.prepareFileUpload({
122
83
  organizationId,
123
84
  name: encodedName,
124
85
  version,
125
- rootFilePath,
126
- filePaths,
127
- branch: branchName,
86
+ filesHash,
87
+ filename: file.keyOnS3,
128
88
  isUpsert: upsert,
129
- isPublic: argv['public'],
130
- batchId: jobId,
131
- batchSize: batchSize,
132
89
  });
133
- }
134
- catch (error) {
135
- if (error.message === 'ORGANIZATION_NOT_FOUND') {
136
- (0, miscellaneous_1.exitWithError)(`Organization ${(0, colorette_1.blue)(organizationId)} not found.`);
90
+ if (file.filePath === filesToUpload.root) {
91
+ rootFilePath = filePath;
137
92
  }
138
- if (error.message === 'API_VERSION_NOT_FOUND') {
139
- (0, miscellaneous_1.exitWithError)(`The definition version ${(0, colorette_1.blue)(`${name}@${version}`)} does not exist in organization ${(0, colorette_1.blue)(organizationId)}!\n${(0, colorette_1.yellow)('Suggestion:')} please use ${(0, colorette_1.blue)('-u')} or ${(0, colorette_1.blue)('--upsert')} to create definition.`);
93
+ filePaths.push(filePath);
94
+ process.stdout.write(`Uploading ${file.contents ? 'bundle for ' : ''}${(0, colorette_1.blue)(file.filePath)}...`);
95
+ const uploadResponse = await uploadFileToS3(signedUploadUrl, file.contents || file.filePath);
96
+ const fileCounter = `(${++uploaded}/${filesToUpload.files.length})`;
97
+ if (!uploadResponse.ok) {
98
+ (0, miscellaneous_1.exitWithError)(`✗ ${fileCounter}\nFile upload failed.`);
140
99
  }
141
- throw error;
100
+ process.stdout.write((0, colorette_1.green)(`✓ ${fileCounter}\n`));
142
101
  }
143
- process.stdout.write(`Definition: ${(0, colorette_1.blue)(api)} is successfully pushed to Redocly API Registry.\n`);
102
+ process.stdout.write('\n');
103
+ await client.registryApi.pushApi({
104
+ organizationId,
105
+ name: encodedName,
106
+ version,
107
+ rootFilePath,
108
+ filePaths,
109
+ branch: branchName,
110
+ isUpsert: upsert,
111
+ isPublic: argv['public'],
112
+ batchId: jobId,
113
+ batchSize: batchSize,
114
+ });
144
115
  }
145
- (0, miscellaneous_1.printExecutionTime)('push', startedAt, api || `apis in organization ${organizationId}`);
146
- });
116
+ catch (error) {
117
+ if (error.message === 'ORGANIZATION_NOT_FOUND') {
118
+ (0, miscellaneous_1.exitWithError)(`Organization ${(0, colorette_1.blue)(organizationId)} not found.`);
119
+ }
120
+ if (error.message === 'API_VERSION_NOT_FOUND') {
121
+ (0, miscellaneous_1.exitWithError)(`The definition version ${(0, colorette_1.blue)(`${name}@${version}`)} does not exist in organization ${(0, colorette_1.blue)(organizationId)}!\n${(0, colorette_1.yellow)('Suggestion:')} please use ${(0, colorette_1.blue)('-u')} or ${(0, colorette_1.blue)('--upsert')} to create definition.`);
122
+ }
123
+ throw error;
124
+ }
125
+ process.stdout.write(`Definition: ${(0, colorette_1.blue)(api)} is successfully pushed to Redocly API Registry.\n`);
126
+ }
127
+ (0, miscellaneous_1.printExecutionTime)('push', startedAt, api || `apis in organization ${organizationId}`);
147
128
  }
148
- exports.handlePush = handlePush;
149
129
  function getFilesList(dir, files) {
150
130
  files = files || [];
151
131
  const filesAndDirs = fs.readdirSync(dir);
@@ -160,82 +140,79 @@ function getFilesList(dir, files) {
160
140
  }
161
141
  return files;
162
142
  }
163
- function collectFilesToUpload(api, config) {
164
- var _a, _b;
165
- return __awaiter(this, void 0, void 0, function* () {
166
- const files = [];
167
- const [{ path: apiPath }] = yield (0, miscellaneous_1.getFallbackApisOrExit)([api], config);
168
- process.stdout.write('Bundling definition\n');
169
- const { bundle: openapiBundle, problems } = yield (0, openapi_core_1.bundle)({
170
- config,
171
- ref: apiPath,
172
- skipRedoclyRegistryRefs: true,
173
- });
174
- const fileTotals = (0, openapi_core_1.getTotals)(problems);
175
- if (fileTotals.errors === 0) {
176
- process.stdout.write(`Created a bundle for ${(0, colorette_1.blue)(api)} ${fileTotals.warnings > 0 ? 'with warnings' : ''}\n`);
177
- }
178
- else {
179
- (0, miscellaneous_1.exitWithError)(`Failed to create a bundle for ${(0, colorette_1.blue)(api)}.`);
180
- }
181
- const fileExt = path.extname(apiPath).split('.').pop();
182
- files.push(getFileEntry(apiPath, (0, miscellaneous_1.dumpBundle)(openapiBundle.parsed, fileExt)));
183
- if (fs.existsSync('package.json')) {
184
- files.push(getFileEntry('package.json'));
143
+ async function collectFilesToUpload(api, config) {
144
+ const files = [];
145
+ const [{ path: apiPath }] = await (0, miscellaneous_1.getFallbackApisOrExit)([api], config);
146
+ process.stdout.write('Bundling definition\n');
147
+ const { bundle: openapiBundle, problems } = await (0, openapi_core_1.bundle)({
148
+ config,
149
+ ref: apiPath,
150
+ skipRedoclyRegistryRefs: true,
151
+ });
152
+ const fileTotals = (0, openapi_core_1.getTotals)(problems);
153
+ if (fileTotals.errors === 0) {
154
+ process.stdout.write(`Created a bundle for ${(0, colorette_1.blue)(api)} ${fileTotals.warnings > 0 ? 'with warnings' : ''}\n`);
155
+ }
156
+ else {
157
+ (0, miscellaneous_1.exitWithError)(`Failed to create a bundle for ${(0, colorette_1.blue)(api)}.`);
158
+ }
159
+ const fileExt = path.extname(apiPath).split('.').pop();
160
+ files.push(getFileEntry(apiPath, (0, miscellaneous_1.dumpBundle)(openapiBundle.parsed, fileExt)));
161
+ if (fs.existsSync('package.json')) {
162
+ files.push(getFileEntry('package.json'));
163
+ }
164
+ if (fs.existsSync(openapi_core_1.IGNORE_FILE)) {
165
+ files.push(getFileEntry(openapi_core_1.IGNORE_FILE));
166
+ }
167
+ if (config.configFile) {
168
+ // All config file paths including the root one
169
+ files.push(...[...new Set(config.styleguide.extendPaths)].map((f) => getFileEntry(f)));
170
+ if (config.theme?.openapi?.htmlTemplate) {
171
+ const dir = getFolder(config.theme.openapi.htmlTemplate);
172
+ const fileList = getFilesList(dir, []);
173
+ files.push(...fileList.map((f) => getFileEntry(f)));
185
174
  }
186
- if (fs.existsSync(openapi_core_1.IGNORE_FILE)) {
187
- files.push(getFileEntry(openapi_core_1.IGNORE_FILE));
175
+ const pluginFiles = new Set();
176
+ for (const plugin of config.styleguide.pluginPaths) {
177
+ if (typeof plugin !== 'string')
178
+ continue;
179
+ const fileList = getFilesList(getFolder(plugin), []);
180
+ fileList.forEach((f) => pluginFiles.add(f));
188
181
  }
189
- if (config.configFile) {
190
- // All config file paths including the root one
191
- files.push(...[...new Set(config.styleguide.extendPaths)].map((f) => getFileEntry(f)));
192
- if ((_b = (_a = config.theme) === null || _a === void 0 ? void 0 : _a.openapi) === null || _b === void 0 ? void 0 : _b.htmlTemplate) {
193
- const dir = getFolder(config.theme.openapi.htmlTemplate);
194
- const fileList = getFilesList(dir, []);
195
- files.push(...fileList.map((f) => getFileEntry(f)));
196
- }
197
- const pluginFiles = new Set();
198
- for (const plugin of config.styleguide.pluginPaths) {
199
- if (typeof plugin !== 'string')
200
- continue;
201
- const fileList = getFilesList(getFolder(plugin), []);
202
- fileList.forEach((f) => pluginFiles.add(f));
182
+ files.push(...filterPluginFilesByExt(Array.from(pluginFiles)).map((f) => getFileEntry(f)));
183
+ }
184
+ if (config.files) {
185
+ const otherFiles = new Set();
186
+ for (const file of config.files) {
187
+ if (fs.statSync(file).isDirectory()) {
188
+ const fileList = getFilesList(file, []);
189
+ fileList.forEach((f) => otherFiles.add(f));
203
190
  }
204
- files.push(...filterPluginFilesByExt(Array.from(pluginFiles)).map((f) => getFileEntry(f)));
205
- }
206
- if (config.files) {
207
- const otherFiles = new Set();
208
- for (const file of config.files) {
209
- if (fs.statSync(file).isDirectory()) {
210
- const fileList = getFilesList(file, []);
211
- fileList.forEach((f) => otherFiles.add(f));
212
- }
213
- else {
214
- otherFiles.add(file);
215
- }
191
+ else {
192
+ otherFiles.add(file);
216
193
  }
217
- files.push(...Array.from(otherFiles).map((f) => getFileEntry(f)));
218
194
  }
195
+ files.push(...Array.from(otherFiles).map((f) => getFileEntry(f)));
196
+ }
197
+ return {
198
+ files,
199
+ root: path.resolve(apiPath),
200
+ };
201
+ function filterPluginFilesByExt(files) {
202
+ return files.filter((file) => {
203
+ const fileExt = path.extname(file).toLowerCase();
204
+ return fileExt === '.js' || fileExt === '.ts' || fileExt === '.mjs' || fileExt === 'json';
205
+ });
206
+ }
207
+ function getFileEntry(filename, contents) {
219
208
  return {
220
- files,
221
- root: path.resolve(apiPath),
209
+ filePath: path.resolve(filename),
210
+ keyOnS3: config.configFile
211
+ ? (0, openapi_core_1.slash)(path.relative(path.dirname(config.configFile), filename))
212
+ : (0, openapi_core_1.slash)(path.basename(filename)),
213
+ contents: (contents && Buffer.from(contents, 'utf-8')) || undefined,
222
214
  };
223
- function filterPluginFilesByExt(files) {
224
- return files.filter((file) => {
225
- const fileExt = path.extname(file).toLowerCase();
226
- return fileExt === '.js' || fileExt === '.ts' || fileExt === '.mjs' || fileExt === 'json';
227
- });
228
- }
229
- function getFileEntry(filename, contents) {
230
- return {
231
- filePath: path.resolve(filename),
232
- keyOnS3: config.configFile
233
- ? (0, openapi_core_1.slash)(path.relative(path.dirname(config.configFile), filename))
234
- : (0, openapi_core_1.slash)(path.basename(filename)),
235
- contents: (contents && Buffer.from(contents, 'utf-8')) || undefined,
236
- };
237
- }
238
- });
215
+ }
239
216
  }
240
217
  function getFolder(filePath) {
241
218
  return path.resolve(path.dirname(filePath));
@@ -246,8 +223,7 @@ function hashFiles(filePaths) {
246
223
  return sum.digest('hex');
247
224
  }
248
225
  function parseDestination(destination) {
249
- var _a;
250
- return (_a = destination === null || destination === void 0 ? void 0 : destination.match(exports.DESTINATION_REGEX)) === null || _a === void 0 ? void 0 : _a.groups;
226
+ return destination?.match(exports.DESTINATION_REGEX)?.groups;
251
227
  }
252
228
  function getDestinationProps(destination, organization) {
253
229
  const groups = destination && parseDestination(destination);
@@ -262,10 +238,7 @@ function getDestinationProps(destination, organization) {
262
238
  return { organizationId: organization, name: undefined, version: undefined };
263
239
  }
264
240
  }
265
- exports.getDestinationProps = getDestinationProps;
266
- const transformPush = (callback) => (_a, config) => {
267
- var _b;
268
- var { apis, branch, 'batch-id': batchId, 'job-id': jobId } = _a, rest = __rest(_a, ["apis", "branch", 'batch-id', 'job-id']);
241
+ const transformPush = (callback) => ({ argv: { apis, branch, 'batch-id': batchId, 'job-id': jobId, ...rest }, config, version, }) => {
269
242
  const [maybeApiOrDestination, maybeDestination, maybeBranchName] = apis || [];
270
243
  if (batchId) {
271
244
  process.stderr.write((0, colorette_1.yellow)(`The ${(0, colorette_1.red)('batch-id')} option is deprecated. Please use ${(0, colorette_1.green)('job-id')} instead.\n\n`));
@@ -286,14 +259,23 @@ const transformPush = (callback) => (_a, config) => {
286
259
  else if (maybeApiOrDestination && !exports.DESTINATION_REGEX.test(maybeApiOrDestination)) {
287
260
  apiFile = maybeApiOrDestination;
288
261
  }
289
- return callback(Object.assign(Object.assign({}, rest), { destination: (_b = rest.destination) !== null && _b !== void 0 ? _b : destination, api: apiFile, branchName: branch !== null && branch !== void 0 ? branch : maybeBranchName, 'job-id': jobId || batchId }), config);
262
+ return callback({
263
+ argv: {
264
+ ...rest,
265
+ destination: rest.destination ?? destination,
266
+ api: apiFile,
267
+ branchName: branch ?? maybeBranchName,
268
+ 'job-id': jobId || batchId,
269
+ },
270
+ config,
271
+ version,
272
+ });
290
273
  };
291
274
  exports.transformPush = transformPush;
292
275
  function getApiRoot({ name, version, config: { apis }, }) {
293
- const api = (apis === null || apis === void 0 ? void 0 : apis[`${name}@${version}`]) || (version === DEFAULT_VERSION && (apis === null || apis === void 0 ? void 0 : apis[name]));
294
- return api === null || api === void 0 ? void 0 : api.root;
276
+ const api = apis?.[`${name}@${version}`] || (version === DEFAULT_VERSION && apis?.[name]);
277
+ return api?.root;
295
278
  }
296
- exports.getApiRoot = getApiRoot;
297
279
  function uploadFileToS3(url, filePathOrBuffer) {
298
280
  const fileSizeInBytes = typeof filePathOrBuffer === 'string'
299
281
  ? fs.statSync(filePathOrBuffer).size