rapidoc 9.3.6 → 9.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +9 -1
- package/dist/index.html +1010 -6
- package/dist/index.html.gz +0 -0
- package/dist/rapidoc-min.js +444 -428
- package/dist/rapidoc-min.js.LICENSE.txt +1 -8
- package/dist/rapidoc-min.js.LICENSE.txt.gz +0 -0
- package/dist/rapidoc-min.js.gz +0 -0
- package/dist/rapidoc-min.js.map +1 -1
- package/dist/rapidoc-min.js.map.gz +0 -0
- package/dist/rapidoc.js +576 -373
- package/dist/report.html +2 -2
- package/index.html +1006 -209
- package/{index1.html → index_bak.html} +13 -6
- package/jsconfig.json +1 -1
- package/package.json +8 -8
- package/src/components/api-request.js +144 -100
- package/src/components/api-response.js +12 -13
- package/src/components/json-tree.js +1 -1
- package/src/components/schema-table.js +16 -6
- package/src/components/schema-tree.js +15 -10
- package/src/json-schema-viewer.js +7 -2
- package/src/rapidoc-mini.js +22 -4
- package/src/rapidoc.js +35 -19
- package/src/styles/border-styles.js +2 -2
- package/src/styles/endpoint-styles.js +13 -10
- package/src/styles/flex-styles.js +1 -1
- package/src/styles/font-styles.js +13 -13
- package/src/styles/input-styles.js +8 -3
- package/src/styles/nav-styles.js +1 -1
- package/src/styles/schema-styles.js +12 -9
- package/src/templates/advance-search-template.js +2 -1
- package/src/templates/callback-template.js +3 -1
- package/src/templates/code-samples-template.js +3 -3
- package/src/templates/endpoint-template.js +33 -28
- package/src/templates/expanded-endpoint-template.js +7 -3
- package/src/templates/json-schema-viewer-template.js +3 -3
- package/src/templates/logo-template.js +1 -1
- package/src/templates/main-body-template.js +6 -17
- package/src/templates/navbar-template.js +6 -6
- package/src/templates/security-scheme-template.js +14 -10
- package/src/utils/common-utils.js +5 -9
- package/src/utils/schema-utils.js +65 -16
- package/src/utils/spec-parser.js +77 -7
- package/src/utils/theme.js +4 -6
|
@@ -120,18 +120,67 @@ export function getTypeInfo(schema) {
|
|
|
120
120
|
return info;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
123
|
+
/**
|
|
124
|
+
*
|
|
125
|
+
* @param {*} ex if the value
|
|
126
|
+
* - Is an Object with 'value' property like
|
|
127
|
+
* { 'value': 'example_val1', 'description': 'some description' }
|
|
128
|
+
* Returns >>>
|
|
129
|
+
* {
|
|
130
|
+
* 'Example': { 'value' : 'example_val1', 'description': 'some description' },
|
|
131
|
+
* }
|
|
132
|
+
* - Is an object where each key represents a valid example object (i,e has a value property)
|
|
133
|
+
* {
|
|
134
|
+
* 'example1': { 'value' : 'example_val1', 'description': 'some description' },
|
|
135
|
+
* 'example2': { 'value' : 'example_val2', 'description': 'some other description' },
|
|
136
|
+
* 'invalid': { 'description': 'invalid example object without any value property' }
|
|
137
|
+
* }
|
|
138
|
+
* Returns >>>
|
|
139
|
+
* {
|
|
140
|
+
* 'example1': { 'value' : 'example_val1', 'description': 'some description' },
|
|
141
|
+
* 'example2': { 'value' : 'example_val2', 'description': 'some other description' }
|
|
142
|
+
* }
|
|
143
|
+
* if none of the keys represents an object with 'value' property then return undefined
|
|
144
|
+
* - Is an array of premitive values
|
|
145
|
+
* ['example_val1', 'example_val2']
|
|
146
|
+
* Returns >>>
|
|
147
|
+
* {
|
|
148
|
+
* 'Example1': {value:'value1'}
|
|
149
|
+
* 'Example2': {value:'value2'}
|
|
150
|
+
* }
|
|
151
|
+
* - Is a premitive value
|
|
152
|
+
* 'example_val1'
|
|
153
|
+
* Returns >>>
|
|
154
|
+
* {
|
|
155
|
+
* 'Example': { 'value': 'example_val1' }
|
|
156
|
+
* }
|
|
157
|
+
* - Is undefined
|
|
158
|
+
* returns undefined
|
|
159
|
+
* @returns
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
export function standardizeExample(ex) {
|
|
163
|
+
if (typeof ex === 'object' && !Array.isArray(ex)) {
|
|
164
|
+
if (ex.value !== undefined) {
|
|
165
|
+
// Case 1: Single object with 'value' property
|
|
166
|
+
return { Example: { ...ex } };
|
|
167
|
+
}
|
|
168
|
+
// Case 2: Object where each key is an object with a 'value' property
|
|
169
|
+
const filteredEntries = Object.entries(ex).filter(([_, obj]) => obj.value !== undefined); // eslint-disable-line
|
|
170
|
+
// If no valid entries found, return JSON.stringify of the input
|
|
171
|
+
if (filteredEntries.length === 0) {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
return Object.fromEntries(filteredEntries);
|
|
175
|
+
} if (Array.isArray(ex)) {
|
|
176
|
+
// Case 3: Array of primitive values
|
|
177
|
+
return ex.reduce((acc, value, index) => {
|
|
178
|
+
acc[`Example${index + 1}`] = { value };
|
|
179
|
+
return acc;
|
|
180
|
+
}, {});
|
|
133
181
|
}
|
|
134
|
-
|
|
182
|
+
// Case 4: Single primitive value
|
|
183
|
+
return ex ? { Example: { value: ex } } : undefined;
|
|
135
184
|
}
|
|
136
185
|
|
|
137
186
|
/**
|
|
@@ -268,7 +317,7 @@ export function getSampleValueByType(schemaObj) {
|
|
|
268
317
|
if (schemaObj.pattern) {
|
|
269
318
|
try {
|
|
270
319
|
return new RandExp(schemaObj.pattern).gen();
|
|
271
|
-
} catch
|
|
320
|
+
} catch {
|
|
272
321
|
return schemaObj.pattern;
|
|
273
322
|
}
|
|
274
323
|
}
|
|
@@ -297,7 +346,7 @@ export function getSampleValueByType(schemaObj) {
|
|
|
297
346
|
case 'ipv6':
|
|
298
347
|
return '2001:0db8:5b96:0000:0000:426f:8e17:642a';
|
|
299
348
|
case 'uuid':
|
|
300
|
-
return [u.
|
|
349
|
+
return [u.substring(0, 8), u.substring(8, 12), `4000-8${u.substring(13, 16)}`, u.substring(16, 28)].join('-');
|
|
301
350
|
case 'byte':
|
|
302
351
|
return 'ZXhhbXBsZQ=='; // 'example' base64 encoded. See https://spec.openapis.org/oas/v3.0.0#data-types
|
|
303
352
|
default:
|
|
@@ -857,7 +906,7 @@ export function schemaInObjectNotation(schema, obj, level = 0, suffix = '') {
|
|
|
857
906
|
}
|
|
858
907
|
|
|
859
908
|
/* Create Example object */
|
|
860
|
-
export function generateExample(schema, mimeType, examples =
|
|
909
|
+
export function generateExample(schema, mimeType, examples = {}, example = {}, includeReadOnly = true, includeWriteOnly = true, outputType = 'json', includeGeneratedExample = false) {
|
|
861
910
|
const finalExamples = [];
|
|
862
911
|
// First check if examples is provided
|
|
863
912
|
if (examples) {
|
|
@@ -876,7 +925,7 @@ export function generateExample(schema, mimeType, examples = '', example = '', i
|
|
|
876
925
|
const fixedJsonString = examples[eg].value;
|
|
877
926
|
egContent = JSON.parse(fixedJsonString);
|
|
878
927
|
egFormat = 'json';
|
|
879
|
-
} catch
|
|
928
|
+
} catch {
|
|
880
929
|
egFormat = 'text';
|
|
881
930
|
egContent = examples[eg].value;
|
|
882
931
|
}
|
|
@@ -910,7 +959,7 @@ export function generateExample(schema, mimeType, examples = '', example = '', i
|
|
|
910
959
|
try {
|
|
911
960
|
egContent = JSON.parse(example);
|
|
912
961
|
egFormat = 'json';
|
|
913
|
-
} catch
|
|
962
|
+
} catch {
|
|
914
963
|
egFormat = 'text';
|
|
915
964
|
egContent = example;
|
|
916
965
|
}
|
package/src/utils/spec-parser.js
CHANGED
|
@@ -3,8 +3,22 @@ import OpenApiParser from '@apitools/openapi-parser';
|
|
|
3
3
|
import { marked } from 'marked';
|
|
4
4
|
import { invalidCharsRegEx, rapidocApiKey, sleep } from '~/utils/common-utils';
|
|
5
5
|
|
|
6
|
-
export default async function ProcessSpec(
|
|
6
|
+
export default async function ProcessSpec(
|
|
7
|
+
specUrl,
|
|
8
|
+
generateMissingTags = false,
|
|
9
|
+
sortTags = false,
|
|
10
|
+
sortSchemas = false,
|
|
11
|
+
sortEndpointsBy = '',
|
|
12
|
+
attrApiKey = '',
|
|
13
|
+
attrApiKeyLocation = '',
|
|
14
|
+
attrApiKeyValue = '',
|
|
15
|
+
serverUrl = '',
|
|
16
|
+
matchPaths = '',
|
|
17
|
+
matchType = '',
|
|
18
|
+
removeEndpointsWithBadgeLabelAs = '',
|
|
19
|
+
) {
|
|
7
20
|
let jsonParsedSpec;
|
|
21
|
+
|
|
8
22
|
try {
|
|
9
23
|
this.requestUpdate(); // important to show the initial loader
|
|
10
24
|
let specMeta;
|
|
@@ -15,7 +29,7 @@ export default async function ProcessSpec(specUrl, generateMissingTags = false,
|
|
|
15
29
|
}
|
|
16
30
|
await sleep(0); // important to show the initial loader (allows for rendering updates)
|
|
17
31
|
|
|
18
|
-
// If
|
|
32
|
+
// If JSON Schema Viewer
|
|
19
33
|
if (specMeta.resolvedSpec?.jsonSchemaViewer && specMeta.resolvedSpec?.schemaAndExamples) {
|
|
20
34
|
this.dispatchEvent(new CustomEvent('before-render', { detail: { spec: specMeta.resolvedSpec } }));
|
|
21
35
|
const schemaAndExamples = Object.entries(specMeta.resolvedSpec.schemaAndExamples).map((v) => ({ show: true, expanded: true, selectedExample: null, name: v[0], elementId: v[0].replace(invalidCharsRegEx, '-'), ...v[1] }));
|
|
@@ -27,8 +41,10 @@ export default async function ProcessSpec(specUrl, generateMissingTags = false,
|
|
|
27
41
|
};
|
|
28
42
|
return parsedSpec;
|
|
29
43
|
}
|
|
44
|
+
|
|
45
|
+
// If RapiDoc or RapiDocMini
|
|
30
46
|
if (specMeta.spec && (specMeta.spec.components || specMeta.spec.info || specMeta.spec.servers || specMeta.spec.tags || specMeta.spec.paths)) {
|
|
31
|
-
jsonParsedSpec = specMeta.spec;
|
|
47
|
+
jsonParsedSpec = filterPaths(specMeta.spec, matchPaths, matchType, removeEndpointsWithBadgeLabelAs);
|
|
32
48
|
this.dispatchEvent(new CustomEvent('before-render', { detail: { spec: jsonParsedSpec } }));
|
|
33
49
|
} else {
|
|
34
50
|
console.info('RapiDoc: %c There was an issue while parsing the spec %o ', 'color:orangered', specMeta); // eslint-disable-line no-console
|
|
@@ -112,7 +128,7 @@ export default async function ProcessSpec(specUrl, generateMissingTags = false,
|
|
|
112
128
|
|
|
113
129
|
// Servers
|
|
114
130
|
let servers = [];
|
|
115
|
-
if (jsonParsedSpec.servers && Array.isArray(jsonParsedSpec.servers)) {
|
|
131
|
+
if (jsonParsedSpec.servers && Array.isArray(jsonParsedSpec.servers) && jsonParsedSpec.servers.length > 0) {
|
|
116
132
|
jsonParsedSpec.servers.forEach((v) => {
|
|
117
133
|
let computedUrl = v.url.trim();
|
|
118
134
|
if (!(computedUrl.startsWith('http') || computedUrl.startsWith('//') || computedUrl.startsWith('{'))) {
|
|
@@ -141,7 +157,7 @@ export default async function ProcessSpec(specUrl, generateMissingTags = false,
|
|
|
141
157
|
} else {
|
|
142
158
|
jsonParsedSpec.servers = [{ url: 'http://localhost', computedUrl: 'http://localhost' }];
|
|
143
159
|
}
|
|
144
|
-
servers = jsonParsedSpec.servers;
|
|
160
|
+
servers = jsonParsedSpec.servers; // eslint-disable-line prefer-destructuring
|
|
145
161
|
const parsedSpec = {
|
|
146
162
|
specLoadError: false,
|
|
147
163
|
isSpecLoading: false,
|
|
@@ -156,6 +172,60 @@ export default async function ProcessSpec(specUrl, generateMissingTags = false,
|
|
|
156
172
|
return parsedSpec;
|
|
157
173
|
}
|
|
158
174
|
|
|
175
|
+
function filterPaths(openApiObject, matchPaths = '', matchType = '', removeEndpointsWithBadgeLabelAs = '') {
|
|
176
|
+
const filteredPaths = {};
|
|
177
|
+
|
|
178
|
+
// Convert the removePathsWithBadgeLabeledAs to an array if provided
|
|
179
|
+
const labelsToRemove = removeEndpointsWithBadgeLabelAs.split(',').map((label) => label.trim().toLowerCase()).filter(Boolean);
|
|
180
|
+
|
|
181
|
+
// Helper function to check if a path should be included based on matchPaths
|
|
182
|
+
function pathMatches(pathsKey, httpMethod) {
|
|
183
|
+
if (!matchPaths) {
|
|
184
|
+
return true; // If no matchPaths provided, include everything
|
|
185
|
+
}
|
|
186
|
+
const fullPath = `${httpMethod} ${pathsKey}`.toLowerCase(); // Construct "method path" string
|
|
187
|
+
if (matchType === 'regex') {
|
|
188
|
+
const regex = new RegExp(matchPaths, 'i');
|
|
189
|
+
return regex.test(matchPaths.toLowerCase());
|
|
190
|
+
}
|
|
191
|
+
return fullPath.includes(matchPaths.toLowerCase());
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Helper function to check if the badges contain any label that needs to be removed
|
|
195
|
+
function containsLabelToRemove(badges) {
|
|
196
|
+
return badges.some((badge) => labelsToRemove.includes(badge?.label.toLowerCase()));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Loop through the paths in the openApiObject
|
|
200
|
+
Object.entries(openApiObject.paths).forEach(([pathsKey, methods]) => {
|
|
201
|
+
const filteredMethods = {};
|
|
202
|
+
|
|
203
|
+
Object.entries(methods).forEach(([httpMethod, methodDetails]) => {
|
|
204
|
+
const badges = methodDetails['x-badges'];
|
|
205
|
+
|
|
206
|
+
// Filter by matchPaths
|
|
207
|
+
if (pathMatches(pathsKey, httpMethod)) {
|
|
208
|
+
if (badges && Array.isArray(badges)) {
|
|
209
|
+
// Filter out based on removePathsWithBadgeLabeledAs
|
|
210
|
+
if (!containsLabelToRemove(badges)) {
|
|
211
|
+
filteredMethods[httpMethod] = methodDetails;
|
|
212
|
+
}
|
|
213
|
+
} else {
|
|
214
|
+
// No badges present, include the method
|
|
215
|
+
filteredMethods[httpMethod] = methodDetails;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
if (Object.keys(filteredMethods).length > 0) {
|
|
221
|
+
filteredPaths[pathsKey] = filteredMethods;
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
openApiObject.paths = filteredPaths;
|
|
226
|
+
return openApiObject;
|
|
227
|
+
}
|
|
228
|
+
|
|
159
229
|
function getHeadersFromMarkdown(markdownContent) {
|
|
160
230
|
const tokens = marked.lexer(markdownContent);
|
|
161
231
|
const headers = tokens.filter((v) => v.type === 'heading' && v.depth <= 2);
|
|
@@ -245,7 +315,7 @@ function getComponents(openApiSpec, sortSchemas = false) {
|
|
|
245
315
|
|
|
246
316
|
function groupByTags(openApiSpec, sortEndpointsBy, generateMissingTags = false, sortTags = false) {
|
|
247
317
|
const supportedMethods = ['get', 'put', 'post', 'delete', 'patch', 'head', 'options']; // this is also used for ordering endpoints by methods
|
|
248
|
-
const tags = openApiSpec.tags && Array.isArray(openApiSpec.tags)
|
|
318
|
+
const tags = openApiSpec.tags && Array.isArray(openApiSpec.tags) && openApiSpec.tags.length > 0
|
|
249
319
|
? openApiSpec.tags.map((v) => ({
|
|
250
320
|
show: true,
|
|
251
321
|
elementId: `tag--${v.name.replace(invalidCharsRegEx, '-')}`,
|
|
@@ -286,7 +356,7 @@ function groupByTags(openApiSpec, sortEndpointsBy, generateMissingTags = false,
|
|
|
286
356
|
pathTags.push(pathOrHookNameKey);
|
|
287
357
|
} else {
|
|
288
358
|
// firstWordEndIndex -= 1;
|
|
289
|
-
pathTags.push(pathOrHookNameKey.
|
|
359
|
+
pathTags.push(pathOrHookNameKey.substring(0, firstWordEndIndex));
|
|
290
360
|
}
|
|
291
361
|
} else {
|
|
292
362
|
pathTags.push('General ⦂');
|
package/src/utils/theme.js
CHANGED
|
@@ -21,8 +21,8 @@ export default function setTheme(baseTheme, theme = {}) {
|
|
|
21
21
|
const fg3 = theme.fg3 ? theme.fg3 : ColorUtils.color.brightness(fg1, -20); // or #aaa
|
|
22
22
|
const lightFg = theme.fg3 ? theme.fg3 : ColorUtils.color.brightness(fg1, -65); // or #777
|
|
23
23
|
const inlineCodeFg = theme.inlineCodeFg ? theme.inlineCodeFg : '#aaa';
|
|
24
|
-
const selectionBg =
|
|
25
|
-
const selectionFg =
|
|
24
|
+
const selectionBg = fg2;
|
|
25
|
+
const selectionFg = bg2;
|
|
26
26
|
|
|
27
27
|
const headerColor = theme.headerColor ? theme.headerColor : ColorUtils.color.brightness(bg1, 10);
|
|
28
28
|
|
|
@@ -107,10 +107,8 @@ export default function setTheme(baseTheme, theme = {}) {
|
|
|
107
107
|
const fg3 = theme.fg3 ? theme.fg3 : ColorUtils.color.brightness(fg1, 30); // or #666
|
|
108
108
|
const lightFg = theme.fg3 ? theme.fg3 : ColorUtils.color.brightness(fg1, 70); // or #999
|
|
109
109
|
const inlineCodeFg = theme.inlineCodeFg ? theme.inlineCodeFg : 'brown';
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
const selectionFg = '#eee';
|
|
113
|
-
|
|
110
|
+
const selectionBg = fg2;
|
|
111
|
+
const selectionFg = bg2;
|
|
114
112
|
const headerColor = theme.headerColor ? theme.headerColor : ColorUtils.color.brightness(bg1, -180);
|
|
115
113
|
|
|
116
114
|
/*
|