@redocly/cli 1.0.0-beta.99 → 1.0.0-rc.2

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 (103) hide show
  1. package/README.md +83 -22
  2. package/bin/cli.js +1 -1
  3. package/lib/__mocks__/@redocly/openapi-core.d.ts +53 -1
  4. package/lib/__mocks__/@redocly/openapi-core.js +56 -5
  5. package/lib/__mocks__/documents.d.ts +92 -0
  6. package/lib/__mocks__/documents.js +63 -0
  7. package/lib/__mocks__/fs.d.ts +2 -0
  8. package/lib/__mocks__/fs.js +3 -1
  9. package/lib/__mocks__/perf_hooks.d.ts +4 -0
  10. package/lib/__mocks__/perf_hooks.js +6 -0
  11. package/lib/__mocks__/redoc.d.ts +7 -0
  12. package/lib/__mocks__/redoc.js +5 -0
  13. package/lib/__mocks__/utils.d.ts +26 -4
  14. package/lib/__mocks__/utils.js +8 -3
  15. package/lib/__tests__/commands/build-docs.test.d.ts +1 -0
  16. package/lib/__tests__/commands/build-docs.test.js +59 -0
  17. package/lib/__tests__/commands/bundle.test.js +66 -30
  18. package/lib/__tests__/commands/join.test.d.ts +1 -0
  19. package/lib/__tests__/commands/join.test.js +85 -0
  20. package/lib/__tests__/commands/lint.test.d.ts +1 -0
  21. package/lib/__tests__/commands/lint.test.js +149 -0
  22. package/lib/__tests__/commands/push-region.test.js +5 -4
  23. package/lib/__tests__/commands/push.test.js +254 -39
  24. package/lib/__tests__/fetch-with-timeout.test.d.ts +1 -0
  25. package/lib/__tests__/fetch-with-timeout.test.js +38 -0
  26. package/lib/__tests__/fixtures/config.d.ts +22 -0
  27. package/lib/__tests__/fixtures/config.js +24 -0
  28. package/lib/__tests__/utils.test.js +429 -1
  29. package/lib/__tests__/wrapper.test.d.ts +1 -0
  30. package/lib/__tests__/wrapper.test.js +57 -0
  31. package/lib/commands/build-docs/index.d.ts +3 -0
  32. package/lib/commands/build-docs/index.js +50 -0
  33. package/{src/commands/preview-docs/preview-server/default.hbs → lib/commands/build-docs/template.hbs} +2 -3
  34. package/lib/commands/build-docs/types.d.ts +23 -0
  35. package/lib/commands/build-docs/types.js +2 -0
  36. package/lib/commands/build-docs/utils.d.ts +7 -0
  37. package/lib/commands/build-docs/utils.js +99 -0
  38. package/lib/commands/bundle.d.ts +10 -12
  39. package/lib/commands/bundle.js +25 -24
  40. package/lib/commands/join.d.ts +12 -3
  41. package/lib/commands/join.js +295 -109
  42. package/lib/commands/lint.d.ts +11 -8
  43. package/lib/commands/lint.js +49 -19
  44. package/lib/commands/login.d.ts +5 -3
  45. package/lib/commands/login.js +2 -2
  46. package/lib/commands/preview-docs/index.d.ts +6 -6
  47. package/lib/commands/preview-docs/index.js +30 -20
  48. package/lib/commands/preview-docs/preview-server/oauth2-redirect.html +1 -1
  49. package/lib/commands/preview-docs/preview-server/preview-server.js +5 -4
  50. package/lib/commands/preview-docs/preview-server/server.d.ts +1 -1
  51. package/lib/commands/push.d.ts +21 -10
  52. package/lib/commands/push.js +110 -63
  53. package/lib/commands/split/__tests__/index.test.js +10 -8
  54. package/lib/commands/split/index.d.ts +5 -3
  55. package/lib/commands/split/index.js +15 -24
  56. package/lib/commands/split/types.d.ts +11 -11
  57. package/lib/commands/split/types.js +19 -19
  58. package/lib/commands/stats.d.ts +7 -4
  59. package/lib/commands/stats.js +13 -12
  60. package/lib/fetch-with-timeout.d.ts +2 -0
  61. package/lib/fetch-with-timeout.js +30 -0
  62. package/lib/index.js +194 -40
  63. package/lib/js-utils.d.ts +1 -0
  64. package/lib/js-utils.js +9 -3
  65. package/lib/types.d.ts +17 -1
  66. package/lib/update-version-notifier.d.ts +3 -0
  67. package/lib/update-version-notifier.js +105 -0
  68. package/lib/utils.d.ts +38 -5
  69. package/lib/utils.js +270 -41
  70. package/lib/wrapper.d.ts +4 -0
  71. package/lib/wrapper.js +52 -0
  72. package/package.json +18 -8
  73. package/src/__mocks__/@redocly/openapi-core.ts +0 -26
  74. package/src/__mocks__/fs.ts +0 -4
  75. package/src/__mocks__/utils.ts +0 -11
  76. package/src/__tests__/commands/bundle.test.ts +0 -120
  77. package/src/__tests__/commands/push-region.test.ts +0 -51
  78. package/src/__tests__/commands/push.test.ts +0 -158
  79. package/src/__tests__/utils.test.ts +0 -50
  80. package/src/assert-node-version.ts +0 -8
  81. package/src/commands/bundle.ts +0 -180
  82. package/src/commands/join.ts +0 -488
  83. package/src/commands/lint.ts +0 -110
  84. package/src/commands/login.ts +0 -21
  85. package/src/commands/preview-docs/index.ts +0 -188
  86. package/src/commands/preview-docs/preview-server/hot.js +0 -42
  87. package/src/commands/preview-docs/preview-server/oauth2-redirect.html +0 -21
  88. package/src/commands/preview-docs/preview-server/preview-server.ts +0 -155
  89. package/src/commands/preview-docs/preview-server/server.ts +0 -91
  90. package/src/commands/push.ts +0 -357
  91. package/src/commands/split/__tests__/fixtures/samples.json +0 -61
  92. package/src/commands/split/__tests__/fixtures/spec.json +0 -70
  93. package/src/commands/split/__tests__/fixtures/webhooks.json +0 -88
  94. package/src/commands/split/__tests__/index.test.ts +0 -117
  95. package/src/commands/split/index.ts +0 -349
  96. package/src/commands/split/types.ts +0 -73
  97. package/src/commands/stats.ts +0 -115
  98. package/src/index.ts +0 -316
  99. package/src/js-utils.ts +0 -12
  100. package/src/types.ts +0 -13
  101. package/src/utils.ts +0 -307
  102. package/tsconfig.json +0 -9
  103. package/tsconfig.tsbuildinfo +0 -1
@@ -20,7 +20,7 @@ var __rest = (this && this.__rest) || function (s, e) {
20
20
  return t;
21
21
  };
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.getApiEntrypoint = exports.transformPush = exports.getDestinationProps = exports.handlePush = void 0;
23
+ exports.getApiRoot = exports.transformPush = exports.getDestinationProps = exports.handlePush = exports.DESTINATION_REGEX = void 0;
24
24
  const fs = require("fs");
25
25
  const path = require("path");
26
26
  const node_fetch_1 = require("node-fetch");
@@ -31,11 +31,10 @@ const openapi_core_1 = require("@redocly/openapi-core");
31
31
  const utils_1 = require("../utils");
32
32
  const login_1 = require("./login");
33
33
  const DEFAULT_VERSION = 'latest';
34
- function handlePush(argv) {
34
+ exports.DESTINATION_REGEX = /^(@(?<organizationId>[\w\-\s]+)\/)?(?<name>[^@]*)@(?<version>[\w\.\-]+)$/;
35
+ function handlePush(argv, config) {
35
36
  return __awaiter(this, void 0, void 0, function* () {
36
- const config = yield openapi_core_1.loadConfig();
37
- const region = argv.region || config.region;
38
- const client = new openapi_core_1.RedoclyClient(region);
37
+ const client = new openapi_core_1.RedoclyClient(config.region);
39
38
  const isAuthorized = yield client.isAuthorizedWithRedoclyByRegion();
40
39
  if (!isAuthorized) {
41
40
  const clientToken = yield login_1.promptClientToken(client.domain);
@@ -43,34 +42,51 @@ function handlePush(argv) {
43
42
  }
44
43
  const startedAt = perf_hooks_1.performance.now();
45
44
  const { destination, branchName, upsert } = argv;
46
- if (destination &&
47
- !(validateDestination(destination) || validateDestinationWithoutOrganization(destination))) {
48
- utils_1.exitWithError(`Destination argument value is not valid, please use the right format: ${colorette_1.yellow('<@organization-id/api-name@api-version>')}`);
45
+ const jobId = argv['job-id'];
46
+ const batchSize = argv['batch-size'];
47
+ if (destination && !exports.DESTINATION_REGEX.test(destination)) {
48
+ utils_1.exitWithError(`Destination argument value is not valid, please use the right format: ${colorette_1.yellow('<api-name@api-version>')}`);
49
49
  }
50
- const [organizationId, name, version] = getDestinationProps(destination, config.organization);
50
+ const destinationProps = getDestinationProps(destination, config.organization);
51
+ const organizationId = argv.organization || destinationProps.organizationId;
52
+ const { name, version } = destinationProps;
51
53
  if (!organizationId) {
52
- return utils_1.exitWithError(`No organization provided, please use the right format: ${colorette_1.yellow('<@organization-id/api-name@api-version>')} or specify the 'organization' field in the config file.`);
54
+ return utils_1.exitWithError(`No organization provided, please use --organization option or specify the 'organization' field in the config file.`);
53
55
  }
54
- const entrypoint = argv.entrypoint || (name && version && getApiEntrypoint({ name, version, config }));
55
- if (name && version && !entrypoint) {
56
- utils_1.exitWithError(`No entrypoint found that matches ${colorette_1.blue(`${name}@${version}`)}. Please make sure you have provided the correct data in the config file.`);
56
+ const api = argv.api || (name && version && getApiRoot({ name, version, config }));
57
+ if (name && version && !api) {
58
+ utils_1.exitWithError(`No api found that matches ${colorette_1.blue(`${name}@${version}`)}. Please make sure you have provided the correct data in the config file.`);
57
59
  }
58
- const apis = entrypoint ? { [`${name}@${version}`]: { root: entrypoint } } : config.apis;
59
- for (const [apiNameAndVersion, { root: entrypoint }] of Object.entries(apis)) {
60
+ // Ensure that a destination for the api is provided.
61
+ if (!name && api) {
62
+ return utils_1.exitWithError(`No destination provided, please use --destination option to provide destination.`);
63
+ }
64
+ if (jobId && !jobId.trim()) {
65
+ utils_1.exitWithError(`The ${colorette_1.blue(`job-id`)} option value is not valid, please avoid using an empty string.`);
66
+ }
67
+ if (batchSize && batchSize < 2) {
68
+ utils_1.exitWithError(`The ${colorette_1.blue(`batch-size`)} option value is not valid, please use the integer bigger than 1.`);
69
+ }
70
+ const apis = api ? { [`${name}@${version}`]: { root: api } } : config.apis;
71
+ if (!Object.keys(apis).length) {
72
+ utils_1.exitWithError(`Api not found. Please make sure you have provided the correct data in the config file.`);
73
+ }
74
+ for (const [apiNameAndVersion, { root: api }] of Object.entries(apis)) {
60
75
  const resolvedConfig = openapi_core_1.getMergedConfig(config, apiNameAndVersion);
61
- resolvedConfig.lint.skipDecorators(argv['skip-decorator']);
76
+ resolvedConfig.styleguide.skipDecorators(argv['skip-decorator']);
62
77
  const [name, version = DEFAULT_VERSION] = apiNameAndVersion.split('@');
78
+ const encodedName = encodeURIComponent(name);
63
79
  try {
64
80
  let rootFilePath = '';
65
81
  const filePaths = [];
66
- const filesToUpload = yield collectFilesToUpload(entrypoint, resolvedConfig);
82
+ const filesToUpload = yield collectFilesToUpload(api, resolvedConfig);
67
83
  const filesHash = hashFiles(filesToUpload.files);
68
84
  process.stdout.write(`Uploading ${filesToUpload.files.length} ${utils_1.pluralize('file', filesToUpload.files.length)}:\n`);
69
85
  let uploaded = 0;
70
- for (let file of filesToUpload.files) {
86
+ for (const file of filesToUpload.files) {
71
87
  const { signedUploadUrl, filePath } = yield client.registryApi.prepareFileUpload({
72
88
  organizationId,
73
- name,
89
+ name: encodedName,
74
90
  version,
75
91
  filesHash,
76
92
  filename: file.keyOnS3,
@@ -91,13 +107,15 @@ function handlePush(argv) {
91
107
  process.stdout.write('\n');
92
108
  yield client.registryApi.pushApi({
93
109
  organizationId,
94
- name,
110
+ name: encodedName,
95
111
  version,
96
112
  rootFilePath,
97
113
  filePaths,
98
114
  branch: branchName,
99
115
  isUpsert: upsert,
100
- isPublic: argv['public']
116
+ isPublic: argv['public'],
117
+ batchId: jobId,
118
+ batchSize: batchSize,
101
119
  });
102
120
  }
103
121
  catch (error) {
@@ -105,14 +123,13 @@ function handlePush(argv) {
105
123
  utils_1.exitWithError(`Organization ${colorette_1.blue(organizationId)} not found`);
106
124
  }
107
125
  if (error.message === 'API_VERSION_NOT_FOUND') {
108
- utils_1.exitWithError(`The definition version ${colorette_1.blue(name)}/${colorette_1.blue(version)} does not exist in organization ${colorette_1.blue(organizationId)}!\n${colorette_1.yellow('Suggestion:')} please use ${colorette_1.blue('-u')} or ${colorette_1.blue('--upsert')} to create definition.
109
- `);
126
+ utils_1.exitWithError(`The definition version ${colorette_1.blue(`${name}@${version}`)} does not exist in organization ${colorette_1.blue(organizationId)}!\n${colorette_1.yellow('Suggestion:')} please use ${colorette_1.blue('-u')} or ${colorette_1.blue('--upsert')} to create definition.\n\n`);
110
127
  }
111
128
  throw error;
112
129
  }
113
- process.stdout.write(`Definition: ${colorette_1.blue(entrypoint)} is successfully pushed to Redocly API Registry \n`);
130
+ process.stdout.write(`Definition: ${colorette_1.blue(api)} is successfully pushed to Redocly API Registry \n`);
114
131
  }
115
- utils_1.printExecutionTime('push', startedAt, entrypoint || `apis in organization ${organizationId}`);
132
+ utils_1.printExecutionTime('push', startedAt, api || `apis in organization ${organizationId}`);
116
133
  });
117
134
  }
118
135
  exports.handlePush = handlePush;
@@ -130,25 +147,26 @@ function getFilesList(dir, files) {
130
147
  }
131
148
  return files;
132
149
  }
133
- function collectFilesToUpload(entrypoint, config) {
150
+ function collectFilesToUpload(api, config) {
151
+ var _a, _b;
134
152
  return __awaiter(this, void 0, void 0, function* () {
135
- let files = [];
136
- const [{ path: entrypointPath }] = yield utils_1.getFallbackEntryPointsOrExit([entrypoint], config);
153
+ const files = [];
154
+ const [{ path: apiPath }] = yield utils_1.getFallbackApisOrExit([api], config);
137
155
  process.stdout.write('Bundling definition\n');
138
156
  const { bundle: openapiBundle, problems } = yield openapi_core_1.bundle({
139
157
  config,
140
- ref: entrypointPath,
158
+ ref: apiPath,
141
159
  skipRedoclyRegistryRefs: true,
142
160
  });
143
161
  const fileTotals = openapi_core_1.getTotals(problems);
144
162
  if (fileTotals.errors === 0) {
145
- process.stdout.write(`Created a bundle for ${colorette_1.blue(entrypoint)} ${fileTotals.warnings > 0 ? 'with warnings' : ''}\n`);
163
+ process.stdout.write(`Created a bundle for ${colorette_1.blue(api)} ${fileTotals.warnings > 0 ? 'with warnings' : ''}\n`);
146
164
  }
147
165
  else {
148
- utils_1.exitWithError(`Failed to create a bundle for ${colorette_1.blue(entrypoint)}\n`);
166
+ utils_1.exitWithError(`Failed to create a bundle for ${colorette_1.blue(api)}\n`);
149
167
  }
150
- const fileExt = path.extname(entrypointPath).split('.').pop();
151
- files.push(getFileEntry(entrypointPath, utils_1.dumpBundle(openapiBundle.parsed, fileExt)));
168
+ const fileExt = path.extname(apiPath).split('.').pop();
169
+ files.push(getFileEntry(apiPath, utils_1.dumpBundle(openapiBundle.parsed, fileExt)));
152
170
  if (fs.existsSync('package.json')) {
153
171
  files.push(getFileEntry('package.json'));
154
172
  }
@@ -157,14 +175,14 @@ function collectFilesToUpload(entrypoint, config) {
157
175
  }
158
176
  if (config.configFile) {
159
177
  // All config file paths including the root one
160
- files.push(...[...new Set(config.lint.extendPaths)].map((f) => getFileEntry(f)));
161
- if (config['features.openapi'].htmlTemplate) {
162
- const dir = getFolder(config['features.openapi'].htmlTemplate);
178
+ files.push(...[...new Set(config.styleguide.extendPaths)].map((f) => getFileEntry(f)));
179
+ if ((_b = (_a = config.theme) === null || _a === void 0 ? void 0 : _a.openapi) === null || _b === void 0 ? void 0 : _b.htmlTemplate) {
180
+ const dir = getFolder(config.theme.openapi.htmlTemplate);
163
181
  const fileList = getFilesList(dir, []);
164
182
  files.push(...fileList.map((f) => getFileEntry(f)));
165
183
  }
166
- let pluginFiles = new Set();
167
- for (const plugin of config.lint.pluginPaths) {
184
+ const pluginFiles = new Set();
185
+ for (const plugin of config.styleguide.pluginPaths) {
168
186
  if (typeof plugin !== 'string')
169
187
  continue;
170
188
  const fileList = getFilesList(getFolder(plugin), []);
@@ -172,9 +190,22 @@ function collectFilesToUpload(entrypoint, config) {
172
190
  }
173
191
  files.push(...filterPluginFilesByExt(Array.from(pluginFiles)).map((f) => getFileEntry(f)));
174
192
  }
193
+ if (config.files) {
194
+ const otherFiles = new Set();
195
+ for (const file of config.files) {
196
+ if (fs.statSync(file).isDirectory()) {
197
+ const fileList = getFilesList(file, []);
198
+ fileList.forEach((f) => otherFiles.add(f));
199
+ }
200
+ else {
201
+ otherFiles.add(file);
202
+ }
203
+ }
204
+ files.push(...Array.from(otherFiles).map((f) => getFileEntry(f)));
205
+ }
175
206
  return {
176
207
  files,
177
- root: path.resolve(entrypointPath),
208
+ root: path.resolve(apiPath),
178
209
  };
179
210
  function filterPluginFilesByExt(files) {
180
211
  return files.filter((file) => {
@@ -197,47 +228,63 @@ function getFolder(filePath) {
197
228
  return path.resolve(path.dirname(filePath));
198
229
  }
199
230
  function hashFiles(filePaths) {
200
- let sum = crypto_1.createHash('sha256');
231
+ const sum = crypto_1.createHash('sha256');
201
232
  filePaths.forEach((file) => sum.update(fs.readFileSync(file.filePath)));
202
233
  return sum.digest('hex');
203
234
  }
204
- function validateDestination(destination) {
205
- const regexp = /^@+([a-zA-Z0-9-_.& ]+)\/+([^@\/]+)@([^@\/]+)$/;
206
- return regexp.test(destination);
207
- }
208
- function validateDestinationWithoutOrganization(destination) {
209
- const regexp = /^()([^@\/]+)@([^@\/]+)$/;
210
- return regexp.test(destination);
235
+ function parseDestination(destination) {
236
+ var _a;
237
+ return (_a = destination === null || destination === void 0 ? void 0 : destination.match(exports.DESTINATION_REGEX)) === null || _a === void 0 ? void 0 : _a.groups;
211
238
  }
212
239
  function getDestinationProps(destination, organization) {
213
- return destination && validateDestination(destination)
214
- ? destination.substring(1).split(/[@\/]/)
215
- : destination && validateDestinationWithoutOrganization(destination)
216
- ? [organization, ...destination.split('@')]
217
- : [organization];
240
+ const groups = destination && parseDestination(destination);
241
+ if (groups) {
242
+ return {
243
+ organizationId: groups.organizationId || organization,
244
+ name: groups.name,
245
+ version: groups.version,
246
+ };
247
+ }
248
+ else {
249
+ return { organizationId: organization, name: undefined, version: undefined };
250
+ }
218
251
  }
219
252
  exports.getDestinationProps = getDestinationProps;
220
- const transformPush = (callback) => (_a) => {
221
- var { maybeEntrypointOrAliasOrDestination, maybeDestination, maybeBranchName, branch } = _a, rest = __rest(_a, ["maybeEntrypointOrAliasOrDestination", "maybeDestination", "maybeBranchName", "branch"]);
222
- if (!!maybeBranchName) {
223
- process.stderr.write(colorette_1.yellow('Deprecation warning: Do not use the third parameter as a branch name. Please use a separate --branch option instead.'));
253
+ const transformPush = (callback) => (_a, config) => {
254
+ var { api: maybeApiOrDestination, maybeDestination, maybeBranchName, branch, 'batch-id': batchId, 'job-id': jobId } = _a, rest = __rest(_a, ["api", "maybeDestination", "maybeBranchName", "branch", 'batch-id', 'job-id']);
255
+ if (batchId) {
256
+ process.stderr.write(colorette_1.yellow(`The ${colorette_1.red('batch-id')} option is deprecated. Please use ${colorette_1.green('job-id')} instead.\n\n`));
257
+ }
258
+ if (maybeBranchName) {
259
+ process.stderr.write(colorette_1.yellow('Deprecation warning: Do not use the third parameter as a branch name. Please use a separate --branch option instead.\n\n'));
260
+ }
261
+ let apiFile, destination;
262
+ if (maybeDestination) {
263
+ process.stderr.write(colorette_1.yellow('Deprecation warning: Do not use the second parameter as a destination. Please use a separate --destination and --organization instead.\n\n'));
264
+ apiFile = maybeApiOrDestination;
265
+ destination = maybeDestination;
266
+ }
267
+ else if (maybeApiOrDestination && exports.DESTINATION_REGEX.test(maybeApiOrDestination)) {
268
+ process.stderr.write(colorette_1.yellow('Deprecation warning: Do not use the first parameter as a destination. Please use a separate --destination and --organization options instead.\n\n'));
269
+ destination = maybeApiOrDestination;
270
+ }
271
+ else if (maybeApiOrDestination && !exports.DESTINATION_REGEX.test(maybeApiOrDestination)) {
272
+ apiFile = maybeApiOrDestination;
224
273
  }
225
- const entrypoint = maybeDestination ? maybeEntrypointOrAliasOrDestination : undefined;
226
- const destination = maybeDestination || maybeEntrypointOrAliasOrDestination;
227
- return callback(Object.assign(Object.assign({}, rest), { destination,
228
- entrypoint, branchName: branch !== null && branch !== void 0 ? branch : maybeBranchName }));
274
+ destination = rest.destination || destination;
275
+ return callback(Object.assign(Object.assign({}, rest), { destination, api: apiFile, branchName: branch !== null && branch !== void 0 ? branch : maybeBranchName, 'job-id': jobId || batchId }), config);
229
276
  };
230
277
  exports.transformPush = transformPush;
231
- function getApiEntrypoint({ name, version, config: { apis }, }) {
278
+ function getApiRoot({ name, version, config: { apis }, }) {
232
279
  const api = (apis === null || apis === void 0 ? void 0 : apis[`${name}@${version}`]) || (version === DEFAULT_VERSION && (apis === null || apis === void 0 ? void 0 : apis[name]));
233
280
  return api === null || api === void 0 ? void 0 : api.root;
234
281
  }
235
- exports.getApiEntrypoint = getApiEntrypoint;
282
+ exports.getApiRoot = getApiRoot;
236
283
  function uploadFileToS3(url, filePathOrBuffer) {
237
284
  const fileSizeInBytes = typeof filePathOrBuffer === 'string'
238
285
  ? fs.statSync(filePathOrBuffer).size
239
286
  : filePathOrBuffer.byteLength;
240
- let readStream = typeof filePathOrBuffer === 'string' ? fs.createReadStream(filePathOrBuffer) : filePathOrBuffer;
287
+ const readStream = typeof filePathOrBuffer === 'string' ? fs.createReadStream(filePathOrBuffer) : filePathOrBuffer;
241
288
  return node_fetch_1.default(url, {
242
289
  method: 'PUT',
243
290
  headers: {
@@ -20,10 +20,10 @@ describe('#split', () => {
20
20
  const openapiDir = 'test';
21
21
  const componentsFiles = {};
22
22
  it('should split the file and show the success message', () => __awaiter(void 0, void 0, void 0, function* () {
23
- const filePath = "packages/cli/src/commands/split/__tests__/fixtures/spec.json";
23
+ const filePath = 'packages/cli/src/commands/split/__tests__/fixtures/spec.json';
24
24
  jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
25
25
  yield index_1.handleSplit({
26
- entrypoint: filePath,
26
+ api: filePath,
27
27
  outDir: openapiDir,
28
28
  separator: '_',
29
29
  });
@@ -33,10 +33,10 @@ describe('#split', () => {
33
33
  expect(process.stderr.write.mock.calls[1][0]).toContain(`${filePath}: split processed in <test>ms`);
34
34
  }));
35
35
  it('should use the correct separator', () => __awaiter(void 0, void 0, void 0, function* () {
36
- const filePath = "packages/cli/src/commands/split/__tests__/fixtures/spec.json";
36
+ const filePath = 'packages/cli/src/commands/split/__tests__/fixtures/spec.json';
37
37
  jest.spyOn(utils, 'pathToFilename').mockImplementation(() => 'newFilePath');
38
38
  yield index_1.handleSplit({
39
- entrypoint: filePath,
39
+ api: filePath,
40
40
  outDir: openapiDir,
41
41
  separator: '_',
42
42
  });
@@ -44,7 +44,7 @@ describe('#split', () => {
44
44
  utils.pathToFilename.mockRestore();
45
45
  }));
46
46
  it('should have correct path with paths', () => {
47
- const openapi = require("./fixtures/spec.json");
47
+ const openapi = require('./fixtures/spec.json');
48
48
  jest.spyOn(openapiCore, 'slash').mockImplementation(() => 'paths/test.yaml');
49
49
  jest.spyOn(path, 'relative').mockImplementation(() => 'paths/test.yaml');
50
50
  index_1.iteratePathItems(openapi.paths, openapiDir, path.join(openapiDir, 'paths'), componentsFiles, '_');
@@ -52,7 +52,7 @@ describe('#split', () => {
52
52
  expect(path.relative).toHaveBeenCalledWith('test', 'test/paths/test.yaml');
53
53
  });
54
54
  it('should have correct path with webhooks', () => {
55
- const openapi = require("./fixtures/webhooks.json");
55
+ const openapi = require('./fixtures/webhooks.json');
56
56
  jest.spyOn(openapiCore, 'slash').mockImplementation(() => 'webhooks/test.yaml');
57
57
  jest.spyOn(path, 'relative').mockImplementation(() => 'webhooks/test.yaml');
58
58
  index_1.iteratePathItems(openapi.webhooks, openapiDir, path.join(openapiDir, 'webhooks'), componentsFiles, 'webhook_');
@@ -60,7 +60,7 @@ describe('#split', () => {
60
60
  expect(path.relative).toHaveBeenCalledWith('test', 'test/webhooks/test.yaml');
61
61
  });
62
62
  it('should have correct path with x-webhooks', () => {
63
- const openapi = require("./fixtures/spec.json");
63
+ const openapi = require('./fixtures/spec.json');
64
64
  jest.spyOn(openapiCore, 'slash').mockImplementation(() => 'webhooks/test.yaml');
65
65
  jest.spyOn(path, 'relative').mockImplementation(() => 'webhooks/test.yaml');
66
66
  index_1.iteratePathItems(openapi['x-webhooks'], openapiDir, path.join(openapiDir, 'webhooks'), componentsFiles, 'webhook_');
@@ -68,7 +68,9 @@ describe('#split', () => {
68
68
  expect(path.relative).toHaveBeenCalledWith('test', 'test/webhooks/test.yaml');
69
69
  });
70
70
  it('should create correct folder name for code samples', () => __awaiter(void 0, void 0, void 0, function* () {
71
- const openapi = require("./fixtures/samples.json");
71
+ const openapi = require('./fixtures/samples.json');
72
+ const fs = require('fs');
73
+ jest.spyOn(fs, 'writeFileSync').mockImplementation(() => { });
72
74
  jest.spyOn(utils, 'escapeLanguageName');
73
75
  index_1.iteratePathItems(openapi.paths, openapiDir, path.join(openapiDir, 'paths'), componentsFiles, '_');
74
76
  expect(utils.escapeLanguageName).nthCalledWith(1, 'C#');
@@ -1,8 +1,10 @@
1
1
  import { Oas3PathItem, Referenced } from './types';
2
- export declare function handleSplit(argv: {
3
- entrypoint: string;
2
+ export declare type SplitOptions = {
3
+ api: string;
4
4
  outDir: string;
5
5
  separator: string;
6
- }): Promise<void>;
6
+ config?: string;
7
+ };
8
+ export declare function handleSplit(argv: SplitOptions): Promise<void>;
7
9
  declare function iteratePathItems(pathItems: Record<string, Referenced<Oas3PathItem>> | undefined, openapiDir: string, outDir: string, componentsFiles: object, pathSeparator: string, codeSamplesPathPrefix?: string): void;
8
10
  export { iteratePathItems };
@@ -22,13 +22,13 @@ const types_1 = require("./types");
22
22
  function handleSplit(argv) {
23
23
  return __awaiter(this, void 0, void 0, function* () {
24
24
  const startedAt = perf_hooks_1.performance.now();
25
- const { entrypoint, outDir, separator } = argv;
26
- validateDefinitionFileName(entrypoint);
27
- const openapi = utils_1.readYaml(entrypoint);
25
+ const { api, outDir, separator } = argv;
26
+ validateDefinitionFileName(api);
27
+ const openapi = utils_1.readYaml(api);
28
28
  splitDefinition(openapi, outDir, separator);
29
- process.stderr.write(`🪓 Document: ${colorette_1.blue(entrypoint)} ${colorette_1.green('is successfully split')}
29
+ process.stderr.write(`🪓 Document: ${colorette_1.blue(api)} ${colorette_1.green('is successfully split')}
30
30
  and all related files are saved to the directory: ${colorette_1.blue(outDir)} \n`);
31
- utils_1.printExecutionTime('split', startedAt, entrypoint);
31
+ utils_1.printExecutionTime('split', startedAt, api);
32
32
  });
33
33
  }
34
34
  exports.handleSplit = handleSplit;
@@ -67,19 +67,6 @@ function validateDefinitionFileName(fileName) {
67
67
  utils_1.exitWithError('File does not conform to the OpenAPI Specification. OpenAPI version is not specified');
68
68
  return true;
69
69
  }
70
- function langToExt(lang) {
71
- const langObj = {
72
- php: '.php',
73
- 'c#': '.cs',
74
- shell: '.sh',
75
- curl: '.sh',
76
- bash: '.sh',
77
- javascript: '.js',
78
- js: '.js',
79
- python: '.py'
80
- };
81
- return langObj[lang];
82
- }
83
70
  function traverseDirectoryDeep(directory, callback, componentsFiles) {
84
71
  if (!fs.existsSync(directory) || !fs.statSync(directory).isDirectory())
85
72
  return;
@@ -169,8 +156,7 @@ function isNotSecurityComponentType(componentType) {
169
156
  return componentType !== types_1.OPENAPI3_COMPONENT.SecuritySchemes;
170
157
  }
171
158
  function findComponentTypes(components) {
172
- return types_1.OPENAPI3_COMPONENT_NAMES
173
- .filter(item => isNotSecurityComponentType(item) && Object.keys(components).includes(item));
159
+ return types_1.OPENAPI3_COMPONENT_NAMES.filter((item) => isNotSecurityComponentType(item) && Object.keys(components).includes(item));
174
160
  }
175
161
  function doesFileDiffer(filename, componentData) {
176
162
  return fs.existsSync(filename) && !isEqual(utils_1.readYaml(filename), componentData);
@@ -198,7 +184,9 @@ function gatherComponentsFiles(components, componentsFiles, componentType, compo
198
184
  var _a, _b;
199
185
  let inherits = [];
200
186
  if (componentType === types_1.OPENAPI3_COMPONENT.Schemas) {
201
- inherits = (((_b = (_a = components === null || components === void 0 ? void 0 : components[componentType]) === null || _a === void 0 ? void 0 : _a[componentName]) === null || _b === void 0 ? void 0 : _b.allOf) || []).map((s) => s.$ref).filter(Boolean);
187
+ inherits = (((_b = (_a = components === null || components === void 0 ? void 0 : components[componentType]) === null || _a === void 0 ? void 0 : _a[componentName]) === null || _b === void 0 ? void 0 : _b.allOf) || [])
188
+ .map(({ $ref }) => $ref)
189
+ .filter(openapi_core_1.isTruthy);
202
190
  }
203
191
  componentsFiles[componentType] = componentsFiles[componentType] || {};
204
192
  componentsFiles[componentType][componentName] = { inherits, filename };
@@ -221,18 +209,19 @@ function iteratePathItems(pathItems, openapiDir, outDir, componentsFiles, pathSe
221
209
  for (const sample of methodDataXCode) {
222
210
  if (sample.source && sample.source.$ref)
223
211
  continue;
224
- const sampleFileName = path.join(openapiDir, 'code_samples', utils_1.escapeLanguageName(sample.lang), codeSamplesPathPrefix + utils_1.pathToFilename(pathName, pathSeparator), method + langToExt(sample.lang));
212
+ const sampleFileName = path.join(openapiDir, 'code_samples', utils_1.escapeLanguageName(sample.lang), codeSamplesPathPrefix + utils_1.pathToFilename(pathName, pathSeparator), method + utils_1.langToExt(sample.lang));
225
213
  fs.mkdirSync(path.dirname(sampleFileName), { recursive: true });
226
214
  fs.writeFileSync(sampleFileName, sample.source);
215
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
227
216
  // @ts-ignore
228
217
  sample.source = {
229
- $ref: openapi_core_1.slash(path.relative(outDir, sampleFileName))
218
+ $ref: openapi_core_1.slash(path.relative(outDir, sampleFileName)),
230
219
  };
231
220
  }
232
221
  }
233
222
  utils_1.writeYaml(pathData, pathFile);
234
223
  pathItems[pathName] = {
235
- $ref: openapi_core_1.slash(path.relative(openapiDir, pathFile))
224
+ $ref: openapi_core_1.slash(path.relative(openapiDir, pathFile)),
236
225
  };
237
226
  traverseDirectoryDeep(outDir, traverseDirectoryDeepCallback, componentsFiles);
238
227
  }
@@ -246,6 +235,7 @@ function iterateComponents(openapi, openapiDir, componentsFiles) {
246
235
  const componentTypes = findComponentTypes(components);
247
236
  componentTypes.forEach(iterateAndGatherComponentsFiles);
248
237
  componentTypes.forEach(iterateComponentTypes);
238
+ // eslint-disable-next-line no-inner-declarations
249
239
  function iterateAndGatherComponentsFiles(componentType) {
250
240
  const componentDirPath = path.join(componentsDir, componentType);
251
241
  for (const componentName of Object.keys((components === null || components === void 0 ? void 0 : components[componentType]) || {})) {
@@ -253,6 +243,7 @@ function iterateComponents(openapi, openapiDir, componentsFiles) {
253
243
  gatherComponentsFiles(components, componentsFiles, componentType, componentName, filename);
254
244
  }
255
245
  }
246
+ // eslint-disable-next-line no-inner-declarations
256
247
  function iterateComponentTypes(componentType) {
257
248
  var _a, _b, _c;
258
249
  const componentDirPath = path.join(componentsDir, componentType);
@@ -1,5 +1,5 @@
1
- import { Oas3Schema, Oas3_1Schema, Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3_1Webhooks, Oas2Definition, Referenced } from "@redocly/openapi-core";
2
- export { Oas3_1Definition, Oas3Definition, Oas2Definition, Oas3Components, Oas3Paths, Oas3PathItem, Oas3ComponentName, Oas3_1Schema, Oas3Schema, Oas3_1Webhooks, Referenced };
1
+ import { Oas3Schema, Oas3_1Schema, Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3_1Webhooks, Oas2Definition, Referenced } from '@redocly/openapi-core';
2
+ export { Oas3_1Definition, Oas3Definition, Oas2Definition, Oas3Components, Oas3Paths, Oas3PathItem, Oas3ComponentName, Oas3_1Schema, Oas3Schema, Oas3_1Webhooks, Referenced, };
3
3
  export declare type Definition = Oas3_1Definition | Oas3Definition | Oas2Definition;
4
4
  export interface ComponentsFiles {
5
5
  [schemas: string]: any;
@@ -12,15 +12,15 @@ export declare const PATHS = "paths";
12
12
  export declare const WEBHOOKS = "webhooks";
13
13
  export declare const xWEBHOOKS = "x-webhooks";
14
14
  export declare const componentsPath: string;
15
- declare enum OPENAPI3_METHOD {
16
- Get = "get",
17
- Put = "put",
18
- Post = "post",
19
- Delete = "delete",
20
- Options = "options",
21
- Head = "head",
22
- Patch = "patch",
23
- Trace = "trace"
15
+ export declare enum OPENAPI3_METHOD {
16
+ get = "get",
17
+ put = "put",
18
+ post = "post",
19
+ delete = "delete",
20
+ options = "options",
21
+ head = "head",
22
+ patch = "patch",
23
+ trace = "trace"
24
24
  }
25
25
  export declare const OPENAPI3_METHOD_NAMES: OPENAPI3_METHOD[];
26
26
  export declare enum OPENAPI3_COMPONENT {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OPENAPI3_COMPONENT_NAMES = exports.OPENAPI3_COMPONENT = exports.OPENAPI3_METHOD_NAMES = exports.componentsPath = exports.xWEBHOOKS = exports.WEBHOOKS = exports.PATHS = exports.COMPONENTS = void 0;
3
+ exports.OPENAPI3_COMPONENT_NAMES = exports.OPENAPI3_COMPONENT = exports.OPENAPI3_METHOD_NAMES = exports.OPENAPI3_METHOD = exports.componentsPath = exports.xWEBHOOKS = exports.WEBHOOKS = exports.PATHS = exports.COMPONENTS = void 0;
4
4
  exports.COMPONENTS = 'components';
5
5
  exports.PATHS = 'paths';
6
6
  exports.WEBHOOKS = 'webhooks';
@@ -8,24 +8,24 @@ exports.xWEBHOOKS = 'x-webhooks';
8
8
  exports.componentsPath = `#/${exports.COMPONENTS}/`;
9
9
  var OPENAPI3_METHOD;
10
10
  (function (OPENAPI3_METHOD) {
11
- OPENAPI3_METHOD["Get"] = "get";
12
- OPENAPI3_METHOD["Put"] = "put";
13
- OPENAPI3_METHOD["Post"] = "post";
14
- OPENAPI3_METHOD["Delete"] = "delete";
15
- OPENAPI3_METHOD["Options"] = "options";
16
- OPENAPI3_METHOD["Head"] = "head";
17
- OPENAPI3_METHOD["Patch"] = "patch";
18
- OPENAPI3_METHOD["Trace"] = "trace";
19
- })(OPENAPI3_METHOD || (OPENAPI3_METHOD = {}));
11
+ OPENAPI3_METHOD["get"] = "get";
12
+ OPENAPI3_METHOD["put"] = "put";
13
+ OPENAPI3_METHOD["post"] = "post";
14
+ OPENAPI3_METHOD["delete"] = "delete";
15
+ OPENAPI3_METHOD["options"] = "options";
16
+ OPENAPI3_METHOD["head"] = "head";
17
+ OPENAPI3_METHOD["patch"] = "patch";
18
+ OPENAPI3_METHOD["trace"] = "trace";
19
+ })(OPENAPI3_METHOD = exports.OPENAPI3_METHOD || (exports.OPENAPI3_METHOD = {}));
20
20
  exports.OPENAPI3_METHOD_NAMES = [
21
- OPENAPI3_METHOD.Get,
22
- OPENAPI3_METHOD.Put,
23
- OPENAPI3_METHOD.Post,
24
- OPENAPI3_METHOD.Delete,
25
- OPENAPI3_METHOD.Options,
26
- OPENAPI3_METHOD.Head,
27
- OPENAPI3_METHOD.Patch,
28
- OPENAPI3_METHOD.Trace
21
+ OPENAPI3_METHOD.get,
22
+ OPENAPI3_METHOD.put,
23
+ OPENAPI3_METHOD.post,
24
+ OPENAPI3_METHOD.delete,
25
+ OPENAPI3_METHOD.options,
26
+ OPENAPI3_METHOD.head,
27
+ OPENAPI3_METHOD.patch,
28
+ OPENAPI3_METHOD.trace,
29
29
  ];
30
30
  var OPENAPI3_COMPONENT;
31
31
  (function (OPENAPI3_COMPONENT) {
@@ -48,5 +48,5 @@ exports.OPENAPI3_COMPONENT_NAMES = [
48
48
  OPENAPI3_COMPONENT.Headers,
49
49
  OPENAPI3_COMPONENT.Links,
50
50
  OPENAPI3_COMPONENT.Callbacks,
51
- OPENAPI3_COMPONENT.SecuritySchemes
51
+ OPENAPI3_COMPONENT.SecuritySchemes,
52
52
  ];
@@ -1,5 +1,8 @@
1
- export declare function handleStats(argv: {
1
+ import { Config } from '@redocly/openapi-core';
2
+ import type { OutputFormat } from '@redocly/openapi-core';
3
+ export declare type StatsOptions = {
4
+ api?: string;
5
+ format: OutputFormat;
2
6
  config?: string;
3
- entrypoint?: string;
4
- format: string;
5
- }): Promise<void>;
7
+ };
8
+ export declare function handleStats(argv: StatsOptions, config: Config): Promise<void>;
@@ -21,7 +21,7 @@ const statsAccumulator = {
21
21
  schemas: { metric: '📈 Schemas', total: 0, color: 'white' },
22
22
  parameters: { metric: '👉 Parameters', total: 0, color: 'yellow', items: new Set() },
23
23
  links: { metric: '🔗 Links', total: 0, color: 'cyan', items: new Set() },
24
- pathItems: { metric: '➡️ Path Items', total: 0, color: 'green' },
24
+ pathItems: { metric: '➡️ Path Items', total: 0, color: 'green' },
25
25
  operations: { metric: '👷 Operations', total: 0, color: 'yellow' },
26
26
  tags: { metric: '🔖 Tags', total: 0, color: 'white', items: new Set() },
27
27
  };
@@ -41,8 +41,8 @@ function printStatsJson(statsAccumulator) {
41
41
  }
42
42
  process.stdout.write(JSON.stringify(json, null, 2));
43
43
  }
44
- function printStats(statsAccumulator, entrypoint, format) {
45
- process.stderr.write(`Document: ${colors.magenta(entrypoint)} stats:\n\n`);
44
+ function printStats(statsAccumulator, api, format) {
45
+ process.stderr.write(`Document: ${colors.magenta(api)} stats:\n\n`);
46
46
  switch (format) {
47
47
  case 'stylish':
48
48
  printStatsStylish(statsAccumulator);
@@ -52,13 +52,12 @@ function printStats(statsAccumulator, entrypoint, format) {
52
52
  break;
53
53
  }
54
54
  }
55
- function handleStats(argv) {
55
+ function handleStats(argv, config) {
56
56
  return __awaiter(this, void 0, void 0, function* () {
57
- const config = yield openapi_core_1.loadConfig(argv.config);
58
- const [{ path }] = yield utils_1.getFallbackEntryPointsOrExit(argv.entrypoint ? [argv.entrypoint] : [], config);
57
+ const [{ path }] = yield utils_1.getFallbackApisOrExit(argv.api ? [argv.api] : [], config);
59
58
  const externalRefResolver = new openapi_core_1.BaseResolver(config.resolve);
60
59
  const { bundle: document } = yield openapi_core_1.bundle({ config, ref: path });
61
- const lintConfig = config.lint;
60
+ const lintConfig = config.styleguide;
62
61
  const oasVersion = openapi_core_1.detectOpenAPI(document.parsed);
63
62
  const oasMajorVersion = openapi_core_1.openAPIMajor(oasVersion);
64
63
  const types = openapi_core_1.normalizeTypes(lintConfig.extendTypes(oasMajorVersion === openapi_core_1.OasMajorVersion.Version3 ? openapi_core_1.Oas3Types : openapi_core_1.Oas2Types, oasVersion), lintConfig);
@@ -70,17 +69,19 @@ function handleStats(argv) {
70
69
  };
71
70
  const resolvedRefMap = yield openapi_core_1.resolveDocument({
72
71
  rootDocument: document,
73
- rootType: types.DefinitionRoot,
72
+ rootType: types.Root,
74
73
  externalRefResolver,
75
74
  });
76
- const statsVisitor = openapi_core_1.normalizeVisitors([{
75
+ const statsVisitor = openapi_core_1.normalizeVisitors([
76
+ {
77
77
  severity: 'warn',
78
78
  ruleId: 'stats',
79
- visitor: openapi_core_1.Stats(statsAccumulator)
80
- }], types);
79
+ visitor: openapi_core_1.Stats(statsAccumulator),
80
+ },
81
+ ], types);
81
82
  openapi_core_1.walkDocument({
82
83
  document,
83
- rootType: types.DefinitionRoot,
84
+ rootType: types.Root,
84
85
  normalizedVisitors: statsVisitor,
85
86
  resolvedRefMap,
86
87
  ctx,
@@ -0,0 +1,2 @@
1
+ declare const _default: (url: string, options?: {}) => Promise<import("node-fetch").Response | undefined>;
2
+ export default _default;