@redocly/cli 0.0.0-snapshot.1737554067

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 (133) hide show
  1. package/README.md +114 -0
  2. package/bin/cli.js +3 -0
  3. package/lib/__mocks__/@redocly/openapi-core.d.ts +99 -0
  4. package/lib/__mocks__/@redocly/openapi-core.js +84 -0
  5. package/lib/__mocks__/documents.d.ts +150 -0
  6. package/lib/__mocks__/documents.js +123 -0
  7. package/lib/__mocks__/fs.d.ts +8 -0
  8. package/lib/__mocks__/fs.js +9 -0
  9. package/lib/__mocks__/perf_hooks.d.ts +3 -0
  10. package/lib/__mocks__/perf_hooks.js +6 -0
  11. package/lib/__mocks__/redoc.d.ts +6 -0
  12. package/lib/__mocks__/redoc.js +5 -0
  13. package/lib/__tests__/commands/build-docs.test.d.ts +1 -0
  14. package/lib/__tests__/commands/build-docs.test.js +54 -0
  15. package/lib/__tests__/commands/bundle.test.d.ts +1 -0
  16. package/lib/__tests__/commands/bundle.test.js +235 -0
  17. package/lib/__tests__/commands/join.test.d.ts +1 -0
  18. package/lib/__tests__/commands/join.test.js +274 -0
  19. package/lib/__tests__/commands/lint.test.d.ts +1 -0
  20. package/lib/__tests__/commands/lint.test.js +149 -0
  21. package/lib/__tests__/commands/push-region.test.d.ts +1 -0
  22. package/lib/__tests__/commands/push-region.test.js +55 -0
  23. package/lib/__tests__/commands/push.test.d.ts +1 -0
  24. package/lib/__tests__/commands/push.test.js +463 -0
  25. package/lib/__tests__/fetch-with-timeout.test.d.ts +1 -0
  26. package/lib/__tests__/fetch-with-timeout.test.js +44 -0
  27. package/lib/__tests__/fixtures/config.d.ts +21 -0
  28. package/lib/__tests__/fixtures/config.js +24 -0
  29. package/lib/__tests__/spinner.test.d.ts +1 -0
  30. package/lib/__tests__/spinner.test.js +43 -0
  31. package/lib/__tests__/utils.test.d.ts +1 -0
  32. package/lib/__tests__/utils.test.js +593 -0
  33. package/lib/__tests__/wrapper.test.d.ts +1 -0
  34. package/lib/__tests__/wrapper.test.js +68 -0
  35. package/lib/cms/api/__tests__/api-keys.test.d.ts +1 -0
  36. package/lib/cms/api/__tests__/api-keys.test.js +26 -0
  37. package/lib/cms/api/__tests__/api.client.test.d.ts +1 -0
  38. package/lib/cms/api/__tests__/api.client.test.js +333 -0
  39. package/lib/cms/api/__tests__/domains.test.d.ts +1 -0
  40. package/lib/cms/api/__tests__/domains.test.js +13 -0
  41. package/lib/cms/api/api-client.d.ts +75 -0
  42. package/lib/cms/api/api-client.js +225 -0
  43. package/lib/cms/api/api-keys.d.ts +1 -0
  44. package/lib/cms/api/api-keys.js +23 -0
  45. package/lib/cms/api/domains.d.ts +1 -0
  46. package/lib/cms/api/domains.js +11 -0
  47. package/lib/cms/api/index.d.ts +3 -0
  48. package/lib/cms/api/index.js +19 -0
  49. package/lib/cms/api/types.d.ts +102 -0
  50. package/lib/cms/api/types.js +2 -0
  51. package/lib/cms/commands/__tests__/push-status.test.d.ts +1 -0
  52. package/lib/cms/commands/__tests__/push-status.test.js +563 -0
  53. package/lib/cms/commands/__tests__/push.test.d.ts +1 -0
  54. package/lib/cms/commands/__tests__/push.test.js +315 -0
  55. package/lib/cms/commands/__tests__/utils.test.d.ts +1 -0
  56. package/lib/cms/commands/__tests__/utils.test.js +51 -0
  57. package/lib/cms/commands/push-status.d.ts +23 -0
  58. package/lib/cms/commands/push-status.js +206 -0
  59. package/lib/cms/commands/push.d.ts +28 -0
  60. package/lib/cms/commands/push.js +142 -0
  61. package/lib/cms/commands/utils.d.ts +25 -0
  62. package/lib/cms/commands/utils.js +46 -0
  63. package/lib/cms/utils.d.ts +2 -0
  64. package/lib/cms/utils.js +6 -0
  65. package/lib/commands/build-docs/index.d.ts +3 -0
  66. package/lib/commands/build-docs/index.js +39 -0
  67. package/lib/commands/build-docs/template.hbs +23 -0
  68. package/lib/commands/build-docs/types.d.ts +23 -0
  69. package/lib/commands/build-docs/types.js +2 -0
  70. package/lib/commands/build-docs/utils.d.ts +7 -0
  71. package/lib/commands/build-docs/utils.js +87 -0
  72. package/lib/commands/bundle.d.ts +14 -0
  73. package/lib/commands/bundle.js +91 -0
  74. package/lib/commands/eject.d.ts +9 -0
  75. package/lib/commands/eject.js +28 -0
  76. package/lib/commands/join.d.ts +11 -0
  77. package/lib/commands/join.js +565 -0
  78. package/lib/commands/lint.d.ts +13 -0
  79. package/lib/commands/lint.js +108 -0
  80. package/lib/commands/login.d.ts +9 -0
  81. package/lib/commands/login.js +23 -0
  82. package/lib/commands/preview-docs/index.d.ts +12 -0
  83. package/lib/commands/preview-docs/index.js +127 -0
  84. package/lib/commands/preview-docs/preview-server/default.hbs +24 -0
  85. package/lib/commands/preview-docs/preview-server/hot.js +59 -0
  86. package/lib/commands/preview-docs/preview-server/oauth2-redirect.html +21 -0
  87. package/lib/commands/preview-docs/preview-server/preview-server.d.ts +5 -0
  88. package/lib/commands/preview-docs/preview-server/preview-server.js +113 -0
  89. package/lib/commands/preview-docs/preview-server/server.d.ts +22 -0
  90. package/lib/commands/preview-docs/preview-server/server.js +85 -0
  91. package/lib/commands/preview-project/constants.d.ts +14 -0
  92. package/lib/commands/preview-project/constants.js +22 -0
  93. package/lib/commands/preview-project/index.d.ts +3 -0
  94. package/lib/commands/preview-project/index.js +56 -0
  95. package/lib/commands/preview-project/types.d.ts +10 -0
  96. package/lib/commands/preview-project/types.js +2 -0
  97. package/lib/commands/push.d.ts +44 -0
  98. package/lib/commands/push.js +295 -0
  99. package/lib/commands/split/__tests__/index.test.d.ts +1 -0
  100. package/lib/commands/split/__tests__/index.test.js +91 -0
  101. package/lib/commands/split/index.d.ts +13 -0
  102. package/lib/commands/split/index.js +259 -0
  103. package/lib/commands/split/types.d.ts +36 -0
  104. package/lib/commands/split/types.js +51 -0
  105. package/lib/commands/stats.d.ts +8 -0
  106. package/lib/commands/stats.js +96 -0
  107. package/lib/commands/translations.d.ts +7 -0
  108. package/lib/commands/translations.js +20 -0
  109. package/lib/index.d.ts +2 -0
  110. package/lib/index.js +733 -0
  111. package/lib/types.d.ts +43 -0
  112. package/lib/types.js +5 -0
  113. package/lib/utils/__mocks__/miscellaneous.d.ts +43 -0
  114. package/lib/utils/__mocks__/miscellaneous.js +24 -0
  115. package/lib/utils/assert-node-version.d.ts +1 -0
  116. package/lib/utils/assert-node-version.js +16 -0
  117. package/lib/utils/fetch-with-timeout.d.ts +7 -0
  118. package/lib/utils/fetch-with-timeout.js +26 -0
  119. package/lib/utils/getCommandNameFromArgs.d.ts +2 -0
  120. package/lib/utils/getCommandNameFromArgs.js +6 -0
  121. package/lib/utils/js-utils.d.ts +5 -0
  122. package/lib/utils/js-utils.js +28 -0
  123. package/lib/utils/miscellaneous.d.ts +81 -0
  124. package/lib/utils/miscellaneous.js +551 -0
  125. package/lib/utils/platform.d.ts +16 -0
  126. package/lib/utils/platform.js +34 -0
  127. package/lib/utils/spinner.d.ts +10 -0
  128. package/lib/utils/spinner.js +42 -0
  129. package/lib/utils/update-version-notifier.d.ts +3 -0
  130. package/lib/utils/update-version-notifier.js +102 -0
  131. package/lib/wrapper.d.ts +11 -0
  132. package/lib/wrapper.js +65 -0
  133. package/package.json +69 -0
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleSplit = handleSplit;
4
+ exports.startsWithComponents = startsWithComponents;
5
+ exports.crawl = crawl;
6
+ exports.iteratePathItems = iteratePathItems;
7
+ const colorette_1 = require("colorette");
8
+ const fs = require("fs");
9
+ const openapi_core_1 = require("@redocly/openapi-core");
10
+ const utils_1 = require("@redocly/openapi-core/lib/utils");
11
+ const path = require("path");
12
+ const perf_hooks_1 = require("perf_hooks");
13
+ const miscellaneous_1 = require("../../utils/miscellaneous");
14
+ const js_utils_1 = require("../../utils/js-utils");
15
+ const types_1 = require("./types");
16
+ async function handleSplit({ argv, collectSpecData }) {
17
+ const startedAt = perf_hooks_1.performance.now();
18
+ const { api, outDir, separator } = argv;
19
+ validateDefinitionFileName(api);
20
+ const ext = (0, miscellaneous_1.getAndValidateFileExtension)(api);
21
+ const openapi = (0, miscellaneous_1.readYaml)(api);
22
+ collectSpecData?.(openapi);
23
+ splitDefinition(openapi, outDir, separator, ext);
24
+ process.stderr.write(`🪓 Document: ${(0, colorette_1.blue)(api)} ${(0, colorette_1.green)('is successfully split')}
25
+ and all related files are saved to the directory: ${(0, colorette_1.blue)(outDir)} \n`);
26
+ (0, miscellaneous_1.printExecutionTime)('split', startedAt, api);
27
+ }
28
+ function splitDefinition(openapi, openapiDir, pathSeparator, ext) {
29
+ fs.mkdirSync(openapiDir, { recursive: true });
30
+ const componentsFiles = {};
31
+ iterateComponents(openapi, openapiDir, componentsFiles, ext);
32
+ iteratePathItems(openapi.paths, openapiDir, path.join(openapiDir, 'paths'), componentsFiles, pathSeparator, undefined, ext);
33
+ const webhooks = openapi.webhooks || openapi['x-webhooks'];
34
+ // use webhook_ prefix for code samples to prevent potential name-clashes with paths samples
35
+ iteratePathItems(webhooks, openapiDir, path.join(openapiDir, 'webhooks'), componentsFiles, pathSeparator, 'webhook_', ext);
36
+ replace$Refs(openapi, openapiDir, componentsFiles);
37
+ (0, miscellaneous_1.writeToFileByExtension)(openapi, path.join(openapiDir, `openapi.${ext}`));
38
+ }
39
+ function startsWithComponents(node) {
40
+ return node.startsWith(`#/${types_1.COMPONENTS}/`);
41
+ }
42
+ function isSupportedExtension(filename) {
43
+ return filename.endsWith('.yaml') || filename.endsWith('.yml') || filename.endsWith('.json');
44
+ }
45
+ function loadFile(fileName) {
46
+ try {
47
+ return (0, openapi_core_1.parseYaml)(fs.readFileSync(fileName, 'utf8'));
48
+ }
49
+ catch (e) {
50
+ return (0, miscellaneous_1.exitWithError)(e.message);
51
+ }
52
+ }
53
+ function validateDefinitionFileName(fileName) {
54
+ if (!fs.existsSync(fileName))
55
+ (0, miscellaneous_1.exitWithError)(`File ${(0, colorette_1.blue)(fileName)} does not exist.`);
56
+ const file = loadFile(fileName);
57
+ if (file.swagger)
58
+ (0, miscellaneous_1.exitWithError)('OpenAPI 2 is not supported by this command.');
59
+ if (!file.openapi)
60
+ (0, miscellaneous_1.exitWithError)('File does not conform to the OpenAPI Specification. OpenAPI version is not specified.');
61
+ return true;
62
+ }
63
+ function traverseDirectoryDeep(directory, callback, componentsFiles) {
64
+ if (!fs.existsSync(directory) || !fs.statSync(directory).isDirectory())
65
+ return;
66
+ const files = fs.readdirSync(directory);
67
+ for (const f of files) {
68
+ const filename = path.join(directory, f);
69
+ if (fs.statSync(filename).isDirectory()) {
70
+ traverseDirectoryDeep(filename, callback, componentsFiles);
71
+ }
72
+ else {
73
+ callback(filename, directory, componentsFiles);
74
+ }
75
+ }
76
+ }
77
+ function traverseDirectoryDeepCallback(filename, directory, componentsFiles) {
78
+ if (!isSupportedExtension(filename))
79
+ return;
80
+ const pathData = (0, miscellaneous_1.readYaml)(filename);
81
+ replace$Refs(pathData, directory, componentsFiles);
82
+ (0, miscellaneous_1.writeToFileByExtension)(pathData, filename);
83
+ }
84
+ function crawl(object, visitor) {
85
+ if (!(0, js_utils_1.isObject)(object))
86
+ return;
87
+ visitor(object);
88
+ for (const key of Object.keys(object)) {
89
+ crawl(object[key], visitor);
90
+ }
91
+ }
92
+ function replace$Refs(obj, relativeFrom, componentFiles = {}) {
93
+ crawl(obj, (node) => {
94
+ if (node.$ref && typeof node.$ref === 'string' && startsWithComponents(node.$ref)) {
95
+ replace(node, '$ref');
96
+ }
97
+ else if ((0, js_utils_1.isObject)(node.discriminator) && (0, js_utils_1.isObject)(node.discriminator.mapping)) {
98
+ const { mapping } = node.discriminator;
99
+ for (const name of Object.keys(mapping)) {
100
+ const mappingPointer = mapping[name];
101
+ if (typeof mappingPointer === 'string' && startsWithComponents(mappingPointer)) {
102
+ replace(node.discriminator.mapping, name);
103
+ }
104
+ }
105
+ }
106
+ });
107
+ function replace(node, key) {
108
+ const splittedNode = node[key].split('/');
109
+ const name = splittedNode.pop();
110
+ const groupName = splittedNode[2];
111
+ const filesGroupName = componentFiles[groupName];
112
+ if (!filesGroupName || !filesGroupName[name])
113
+ return;
114
+ let filename = path.relative(relativeFrom, filesGroupName[name].filename);
115
+ if (!filename.startsWith('.')) {
116
+ filename = '.' + path.sep + filename;
117
+ }
118
+ node[key] = filename;
119
+ }
120
+ }
121
+ function implicitlyReferenceDiscriminator(obj, defName, filename, schemaFiles) {
122
+ if (!obj.discriminator)
123
+ return;
124
+ const defPtr = `#/${types_1.COMPONENTS}/${types_1.OPENAPI3_COMPONENT.Schemas}/${defName}`;
125
+ const implicitMapping = {};
126
+ for (const [name, { inherits, filename: parentFilename }] of Object.entries(schemaFiles)) {
127
+ if (inherits.indexOf(defPtr) > -1) {
128
+ const res = path.relative(path.dirname(filename), parentFilename);
129
+ implicitMapping[name] = res.startsWith('.') ? res : '.' + path.sep + res;
130
+ }
131
+ }
132
+ if ((0, js_utils_1.isEmptyObject)(implicitMapping))
133
+ return;
134
+ const discriminatorPropSchema = obj.properties[obj.discriminator.propertyName];
135
+ const discriminatorEnum = discriminatorPropSchema && discriminatorPropSchema.enum;
136
+ const mapping = (obj.discriminator.mapping = obj.discriminator.mapping || {});
137
+ for (const name of Object.keys(implicitMapping)) {
138
+ if (discriminatorEnum && !discriminatorEnum.includes(name)) {
139
+ continue;
140
+ }
141
+ if (mapping[name] && mapping[name] !== implicitMapping[name]) {
142
+ process.stderr.write((0, colorette_1.yellow)(`warning: explicit mapping overlaps with local mapping entry ${(0, colorette_1.red)(name)} at ${(0, colorette_1.blue)(filename)}. Please check it.`));
143
+ }
144
+ mapping[name] = implicitMapping[name];
145
+ }
146
+ }
147
+ function isNotSecurityComponentType(componentType) {
148
+ return componentType !== types_1.OPENAPI3_COMPONENT.SecuritySchemes;
149
+ }
150
+ function findComponentTypes(components) {
151
+ return types_1.OPENAPI3_COMPONENT_NAMES.filter((item) => isNotSecurityComponentType(item) && Object.keys(components).includes(item));
152
+ }
153
+ function doesFileDiffer(filename, componentData) {
154
+ return fs.existsSync(filename) && !(0, utils_1.dequal)((0, miscellaneous_1.readYaml)(filename), componentData);
155
+ }
156
+ function removeEmptyComponents(openapi, componentType) {
157
+ if (openapi.components && (0, js_utils_1.isEmptyObject)(openapi.components[componentType])) {
158
+ delete openapi.components[componentType];
159
+ }
160
+ if ((0, js_utils_1.isEmptyObject)(openapi.components)) {
161
+ delete openapi.components;
162
+ }
163
+ }
164
+ function createComponentDir(componentDirPath, componentType) {
165
+ if (isNotSecurityComponentType(componentType)) {
166
+ fs.mkdirSync(componentDirPath, { recursive: true });
167
+ }
168
+ }
169
+ function extractFileNameFromPath(filename) {
170
+ return path.basename(filename, path.extname(filename));
171
+ }
172
+ function getFileNamePath(componentDirPath, componentName, ext) {
173
+ return path.join(componentDirPath, componentName) + `.${ext}`;
174
+ }
175
+ function gatherComponentsFiles(components, componentsFiles, componentType, componentName, filename) {
176
+ let inherits = [];
177
+ if (componentType === types_1.OPENAPI3_COMPONENT.Schemas) {
178
+ inherits = (components?.[componentType]?.[componentName]?.allOf || [])
179
+ .map(({ $ref }) => $ref)
180
+ .filter(openapi_core_1.isTruthy);
181
+ }
182
+ componentsFiles[componentType] = componentsFiles[componentType] || {};
183
+ componentsFiles[componentType][componentName] = { inherits, filename };
184
+ }
185
+ function iteratePathItems(pathItems, openapiDir, outDir, componentsFiles, pathSeparator, codeSamplesPathPrefix = '', ext) {
186
+ if (!pathItems)
187
+ return;
188
+ fs.mkdirSync(outDir, { recursive: true });
189
+ for (const pathName of Object.keys(pathItems)) {
190
+ const pathFile = `${path.join(outDir, (0, miscellaneous_1.pathToFilename)(pathName, pathSeparator))}.${ext}`;
191
+ const pathData = pathItems[pathName];
192
+ if ((0, openapi_core_1.isRef)(pathData))
193
+ continue;
194
+ for (const method of types_1.OPENAPI3_METHOD_NAMES) {
195
+ const methodData = pathData[method];
196
+ const methodDataXCode = methodData?.['x-code-samples'] || methodData?.['x-codeSamples'];
197
+ if (!methodDataXCode || !Array.isArray(methodDataXCode)) {
198
+ continue;
199
+ }
200
+ for (const sample of methodDataXCode) {
201
+ if (sample.source && sample.source.$ref)
202
+ continue;
203
+ const sampleFileName = path.join(openapiDir, 'code_samples', (0, miscellaneous_1.escapeLanguageName)(sample.lang), codeSamplesPathPrefix + (0, miscellaneous_1.pathToFilename)(pathName, pathSeparator), method + (0, miscellaneous_1.langToExt)(sample.lang));
204
+ fs.mkdirSync(path.dirname(sampleFileName), { recursive: true });
205
+ fs.writeFileSync(sampleFileName, sample.source);
206
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
207
+ // @ts-ignore
208
+ sample.source = {
209
+ $ref: (0, openapi_core_1.slash)(path.relative(outDir, sampleFileName)),
210
+ };
211
+ }
212
+ }
213
+ (0, miscellaneous_1.writeToFileByExtension)(pathData, pathFile);
214
+ pathItems[pathName] = {
215
+ $ref: (0, openapi_core_1.slash)(path.relative(openapiDir, pathFile)),
216
+ };
217
+ traverseDirectoryDeep(outDir, traverseDirectoryDeepCallback, componentsFiles);
218
+ }
219
+ }
220
+ function iterateComponents(openapi, openapiDir, componentsFiles, ext) {
221
+ const { components } = openapi;
222
+ if (components) {
223
+ const componentsDir = path.join(openapiDir, types_1.COMPONENTS);
224
+ fs.mkdirSync(componentsDir, { recursive: true });
225
+ const componentTypes = findComponentTypes(components);
226
+ componentTypes.forEach(iterateAndGatherComponentsFiles);
227
+ componentTypes.forEach(iterateComponentTypes);
228
+ // eslint-disable-next-line no-inner-declarations
229
+ function iterateAndGatherComponentsFiles(componentType) {
230
+ const componentDirPath = path.join(componentsDir, componentType);
231
+ for (const componentName of Object.keys(components?.[componentType] || {})) {
232
+ const filename = getFileNamePath(componentDirPath, componentName, ext);
233
+ gatherComponentsFiles(components, componentsFiles, componentType, componentName, filename);
234
+ }
235
+ }
236
+ // eslint-disable-next-line no-inner-declarations
237
+ function iterateComponentTypes(componentType) {
238
+ const componentDirPath = path.join(componentsDir, componentType);
239
+ createComponentDir(componentDirPath, componentType);
240
+ for (const componentName of Object.keys(components?.[componentType] || {})) {
241
+ const filename = getFileNamePath(componentDirPath, componentName, ext);
242
+ const componentData = components?.[componentType]?.[componentName];
243
+ replace$Refs(componentData, path.dirname(filename), componentsFiles);
244
+ implicitlyReferenceDiscriminator(componentData, extractFileNameFromPath(filename), filename, componentsFiles.schemas || {});
245
+ if (doesFileDiffer(filename, componentData)) {
246
+ process.stderr.write((0, colorette_1.yellow)(`warning: conflict for ${componentName} - file already exists with different content: ${(0, colorette_1.blue)(filename)} ... Skip.\n`));
247
+ }
248
+ else {
249
+ (0, miscellaneous_1.writeToFileByExtension)(componentData, filename);
250
+ }
251
+ if (isNotSecurityComponentType(componentType)) {
252
+ // security schemas must referenced from components
253
+ delete openapi.components?.[componentType]?.[componentName];
254
+ }
255
+ }
256
+ removeEmptyComponents(openapi, componentType);
257
+ }
258
+ }
259
+ }
@@ -0,0 +1,36 @@
1
+ import type { Oas2Definition } from '@redocly/openapi-core';
2
+ import type { Oas3_1Definition, Oas3Definition } from '@redocly/openapi-core/lib/typings/openapi';
3
+ export type Definition = Oas3_1Definition | Oas3Definition | Oas2Definition;
4
+ export interface ComponentsFiles {
5
+ [schemas: string]: any;
6
+ }
7
+ export interface RefObject {
8
+ [$ref: string]: string;
9
+ }
10
+ export declare const COMPONENTS = "components";
11
+ export declare const PATHS = "paths";
12
+ export declare const WEBHOOKS = "webhooks";
13
+ export declare const xWEBHOOKS = "x-webhooks";
14
+ export declare enum OPENAPI3_METHOD {
15
+ get = "get",
16
+ put = "put",
17
+ post = "post",
18
+ delete = "delete",
19
+ options = "options",
20
+ head = "head",
21
+ patch = "patch",
22
+ trace = "trace"
23
+ }
24
+ export declare const OPENAPI3_METHOD_NAMES: OPENAPI3_METHOD[];
25
+ export declare enum OPENAPI3_COMPONENT {
26
+ Schemas = "schemas",
27
+ Responses = "responses",
28
+ Parameters = "parameters",
29
+ Examples = "examples",
30
+ Headers = "headers",
31
+ RequestBodies = "requestBodies",
32
+ Links = "links",
33
+ Callbacks = "callbacks",
34
+ SecuritySchemes = "securitySchemes"
35
+ }
36
+ export declare const OPENAPI3_COMPONENT_NAMES: OPENAPI3_COMPONENT[];
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OPENAPI3_COMPONENT_NAMES = exports.OPENAPI3_COMPONENT = exports.OPENAPI3_METHOD_NAMES = exports.OPENAPI3_METHOD = exports.xWEBHOOKS = exports.WEBHOOKS = exports.PATHS = exports.COMPONENTS = void 0;
4
+ exports.COMPONENTS = 'components';
5
+ exports.PATHS = 'paths';
6
+ exports.WEBHOOKS = 'webhooks';
7
+ exports.xWEBHOOKS = 'x-webhooks';
8
+ var OPENAPI3_METHOD;
9
+ (function (OPENAPI3_METHOD) {
10
+ OPENAPI3_METHOD["get"] = "get";
11
+ OPENAPI3_METHOD["put"] = "put";
12
+ OPENAPI3_METHOD["post"] = "post";
13
+ OPENAPI3_METHOD["delete"] = "delete";
14
+ OPENAPI3_METHOD["options"] = "options";
15
+ OPENAPI3_METHOD["head"] = "head";
16
+ OPENAPI3_METHOD["patch"] = "patch";
17
+ OPENAPI3_METHOD["trace"] = "trace";
18
+ })(OPENAPI3_METHOD || (exports.OPENAPI3_METHOD = OPENAPI3_METHOD = {}));
19
+ exports.OPENAPI3_METHOD_NAMES = [
20
+ OPENAPI3_METHOD.get,
21
+ OPENAPI3_METHOD.put,
22
+ OPENAPI3_METHOD.post,
23
+ OPENAPI3_METHOD.delete,
24
+ OPENAPI3_METHOD.options,
25
+ OPENAPI3_METHOD.head,
26
+ OPENAPI3_METHOD.patch,
27
+ OPENAPI3_METHOD.trace,
28
+ ];
29
+ var OPENAPI3_COMPONENT;
30
+ (function (OPENAPI3_COMPONENT) {
31
+ OPENAPI3_COMPONENT["Schemas"] = "schemas";
32
+ OPENAPI3_COMPONENT["Responses"] = "responses";
33
+ OPENAPI3_COMPONENT["Parameters"] = "parameters";
34
+ OPENAPI3_COMPONENT["Examples"] = "examples";
35
+ OPENAPI3_COMPONENT["Headers"] = "headers";
36
+ OPENAPI3_COMPONENT["RequestBodies"] = "requestBodies";
37
+ OPENAPI3_COMPONENT["Links"] = "links";
38
+ OPENAPI3_COMPONENT["Callbacks"] = "callbacks";
39
+ OPENAPI3_COMPONENT["SecuritySchemes"] = "securitySchemes";
40
+ })(OPENAPI3_COMPONENT || (exports.OPENAPI3_COMPONENT = OPENAPI3_COMPONENT = {}));
41
+ exports.OPENAPI3_COMPONENT_NAMES = [
42
+ OPENAPI3_COMPONENT.RequestBodies,
43
+ OPENAPI3_COMPONENT.Schemas,
44
+ OPENAPI3_COMPONENT.Responses,
45
+ OPENAPI3_COMPONENT.Parameters,
46
+ OPENAPI3_COMPONENT.Examples,
47
+ OPENAPI3_COMPONENT.Headers,
48
+ OPENAPI3_COMPONENT.Links,
49
+ OPENAPI3_COMPONENT.Callbacks,
50
+ OPENAPI3_COMPONENT.SecuritySchemes,
51
+ ];
@@ -0,0 +1,8 @@
1
+ import type { OutputFormat } from '@redocly/openapi-core';
2
+ import type { CommandArgs } from '../wrapper';
3
+ import type { VerifyConfigOptions } from '../types';
4
+ export type StatsOptions = {
5
+ api?: string;
6
+ format: OutputFormat;
7
+ } & VerifyConfigOptions;
8
+ export declare function handleStats({ argv, config, collectSpecData }: CommandArgs<StatsOptions>): Promise<void>;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleStats = handleStats;
4
+ const perf_hooks_1 = require("perf_hooks");
5
+ const colors = require("colorette");
6
+ const openapi_core_1 = require("@redocly/openapi-core");
7
+ const miscellaneous_1 = require("../utils/miscellaneous");
8
+ const statsAccumulator = {
9
+ refs: { metric: '🚗 References', total: 0, color: 'red', items: new Set() },
10
+ externalDocs: { metric: '📦 External Documents', total: 0, color: 'magenta' },
11
+ schemas: { metric: '📈 Schemas', total: 0, color: 'white' },
12
+ parameters: { metric: '👉 Parameters', total: 0, color: 'yellow', items: new Set() },
13
+ links: { metric: '🔗 Links', total: 0, color: 'cyan', items: new Set() },
14
+ pathItems: { metric: '🔀 Path Items', total: 0, color: 'green' },
15
+ webhooks: { metric: '🎣 Webhooks', total: 0, color: 'green' },
16
+ operations: { metric: '👷 Operations', total: 0, color: 'yellow' },
17
+ tags: { metric: '🔖 Tags', total: 0, color: 'white', items: new Set() },
18
+ };
19
+ function printStatsStylish(statsAccumulator) {
20
+ for (const node in statsAccumulator) {
21
+ const { metric, total, color } = statsAccumulator[node];
22
+ process.stderr.write(colors[color](`${metric}: ${total} \n`));
23
+ }
24
+ }
25
+ function printStatsJson(statsAccumulator) {
26
+ const json = {};
27
+ for (const key of Object.keys(statsAccumulator)) {
28
+ json[key] = {
29
+ metric: statsAccumulator[key].metric,
30
+ total: statsAccumulator[key].total,
31
+ };
32
+ }
33
+ process.stdout.write(JSON.stringify(json, null, 2));
34
+ }
35
+ function printStatsMarkdown(statsAccumulator) {
36
+ let output = '| Feature | Count |\n| --- | --- |\n';
37
+ for (const key of Object.keys(statsAccumulator)) {
38
+ output +=
39
+ '| ' +
40
+ statsAccumulator[key].metric +
41
+ ' | ' +
42
+ statsAccumulator[key].total +
43
+ ' |\n';
44
+ }
45
+ process.stdout.write(output);
46
+ }
47
+ function printStats(statsAccumulator, api, startedAt, format) {
48
+ switch (format) {
49
+ case 'stylish':
50
+ process.stderr.write(`Document: ${colors.magenta(api)} stats:\n\n`);
51
+ printStatsStylish(statsAccumulator);
52
+ (0, miscellaneous_1.printExecutionTime)('stats', startedAt, api);
53
+ break;
54
+ case 'json':
55
+ printStatsJson(statsAccumulator);
56
+ break;
57
+ case 'markdown':
58
+ printStatsMarkdown(statsAccumulator);
59
+ break;
60
+ }
61
+ }
62
+ async function handleStats({ argv, config, collectSpecData }) {
63
+ const [{ path }] = await (0, miscellaneous_1.getFallbackApisOrExit)(argv.api ? [argv.api] : [], config);
64
+ const externalRefResolver = new openapi_core_1.BaseResolver(config.resolve);
65
+ const { bundle: document } = await (0, openapi_core_1.bundle)({ config, ref: path });
66
+ collectSpecData?.(document.parsed);
67
+ const lintConfig = config.styleguide;
68
+ const specVersion = (0, openapi_core_1.detectSpec)(document.parsed);
69
+ const types = (0, openapi_core_1.normalizeTypes)(lintConfig.extendTypes((0, openapi_core_1.getTypes)(specVersion), specVersion), lintConfig);
70
+ const startedAt = perf_hooks_1.performance.now();
71
+ const ctx = {
72
+ problems: [],
73
+ oasVersion: specVersion,
74
+ visitorsData: {},
75
+ };
76
+ const resolvedRefMap = await (0, openapi_core_1.resolveDocument)({
77
+ rootDocument: document,
78
+ rootType: types.Root,
79
+ externalRefResolver,
80
+ });
81
+ const statsVisitor = (0, openapi_core_1.normalizeVisitors)([
82
+ {
83
+ severity: 'warn',
84
+ ruleId: 'stats',
85
+ visitor: (0, openapi_core_1.Stats)(statsAccumulator),
86
+ },
87
+ ], types);
88
+ (0, openapi_core_1.walkDocument)({
89
+ document,
90
+ rootType: types.Root,
91
+ normalizedVisitors: statsVisitor,
92
+ resolvedRefMap,
93
+ ctx,
94
+ });
95
+ printStats(statsAccumulator, path, startedAt, argv.format);
96
+ }
@@ -0,0 +1,7 @@
1
+ import type { CommandArgs } from '../wrapper';
2
+ import type { VerifyConfigOptions } from '../types';
3
+ export type TranslationsOptions = {
4
+ locale: string;
5
+ 'project-dir'?: string;
6
+ } & VerifyConfigOptions;
7
+ export declare const handleTranslations: ({ argv }: CommandArgs<TranslationsOptions>) => Promise<void>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleTranslations = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const platform_1 = require("../utils/platform");
6
+ const handleTranslations = async ({ argv }) => {
7
+ process.stdout.write(`\nLaunching translate using NPX.\n\n`);
8
+ const { npxExecutableName, sanitize, shell } = (0, platform_1.getPlatformSpawnArgs)();
9
+ const projectDir = sanitize(argv['project-dir'], platform_1.sanitizePath);
10
+ const locale = sanitize(argv.locale, platform_1.sanitizeLocale);
11
+ const child = (0, child_process_1.spawn)(npxExecutableName, ['-y', '@redocly/realm', 'translate', locale, `-d=${projectDir}`], {
12
+ stdio: 'inherit',
13
+ shell,
14
+ });
15
+ child.on('error', (error) => {
16
+ process.stderr.write(`Translate launch failed: ${error.message}`);
17
+ throw new Error(`Translate launch failed.`);
18
+ });
19
+ };
20
+ exports.handleTranslations = handleTranslations;
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import './utils/assert-node-version';