rapidoc 11.0.1 → 12.1.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 (96) hide show
  1. package/README.md +171 -54
  2. package/dist/rapidoc-flow-min.js +580 -0
  3. package/dist/rapidoc-flow-min.js.LICENSE.txt +171 -0
  4. package/dist/rapidoc-min.js +645 -202
  5. package/dist/rapidoc-min.js.LICENSE.txt +381 -0
  6. package/package.json +57 -42
  7. package/src/README.md +150 -0
  8. package/src/components/README.md +91 -0
  9. package/src/components/api-request.ts +912 -0
  10. package/src/components/api-response.ts +514 -0
  11. package/src/components/json-tree.ts +171 -0
  12. package/src/components/schema-base-element.ts +329 -0
  13. package/src/components/schema-table.ts +475 -0
  14. package/src/components/schema-tree.ts +393 -0
  15. package/src/components/tag-input.ts +180 -0
  16. package/src/flow.js +3 -0
  17. package/src/index.js +6 -0
  18. package/src/oauth-receiver.ts +29 -0
  19. package/src/rapi-flow.ts +1178 -0
  20. package/src/rapidoc-mini.ts +603 -0
  21. package/src/rapidoc.ts +1854 -0
  22. package/src/styles/README.md +96 -0
  23. package/src/styles/auth-styles.js +318 -0
  24. package/src/styles/border-styles.js +24 -0
  25. package/src/styles/css-bundle.js +129 -0
  26. package/src/styles/custom-styles.js +8 -0
  27. package/src/styles/dialog-box-styles.js +102 -0
  28. package/src/styles/endpoint-styles.js +564 -0
  29. package/src/styles/flex-styles.js +16 -0
  30. package/src/styles/flow-styles.js +248 -0
  31. package/src/styles/font-styles.js +432 -0
  32. package/src/styles/info-styles.js +36 -0
  33. package/src/styles/input-styles.js +555 -0
  34. package/src/styles/layout-styles.js +396 -0
  35. package/src/styles/microlighter-styles.js +99 -0
  36. package/src/styles/nav-styles.js +633 -0
  37. package/src/styles/param-list-styles.js +261 -0
  38. package/src/styles/schema-styles.js +296 -0
  39. package/src/styles/tab-styles.js +106 -0
  40. package/src/styles/theme-tokens.js +582 -0
  41. package/src/templates/README.md +89 -0
  42. package/src/templates/advanced-search-dialog-template.js +94 -0
  43. package/src/templates/api-response-template.js +223 -0
  44. package/src/templates/callback-template.js +86 -0
  45. package/src/templates/code-samples-template.js +52 -0
  46. package/src/templates/components-template.js +86 -0
  47. package/src/templates/downloads-template.js +70 -0
  48. package/src/templates/endpoint-template.js +377 -0
  49. package/src/templates/expanded-endpoint-template.js +270 -0
  50. package/src/templates/focused-endpoint-template.js +146 -0
  51. package/src/templates/header-template.js +92 -0
  52. package/src/templates/logo-template.js +21 -0
  53. package/src/templates/main-body-template.js +102 -0
  54. package/src/templates/navbar-template.js +498 -0
  55. package/src/templates/overview-template.js +104 -0
  56. package/src/templates/request-body-template.js +673 -0
  57. package/src/templates/request-params-template.js +485 -0
  58. package/src/templates/security-scheme-template.js +1272 -0
  59. package/src/templates/server-template.js +153 -0
  60. package/src/utils/README.md +146 -0
  61. package/src/utils/arazzo/README.md +119 -0
  62. package/src/utils/arazzo/components.js +15 -0
  63. package/src/utils/arazzo/graph.js +269 -0
  64. package/src/utils/arazzo/index.js +52 -0
  65. package/src/utils/arazzo/operations.js +106 -0
  66. package/src/utils/arazzo/parse.js +196 -0
  67. package/src/utils/arazzo/refs.js +40 -0
  68. package/src/utils/arazzo/svg.js +707 -0
  69. package/src/utils/auto-color-scheme.js +99 -0
  70. package/src/utils/bind-navbar.js +175 -0
  71. package/src/utils/color-utils.js +59 -0
  72. package/src/utils/common-utils.js +191 -0
  73. package/src/utils/curl-utils.js +126 -0
  74. package/src/utils/highlighter.js +419 -0
  75. package/src/utils/markdown-utils.js +110 -0
  76. package/src/utils/mcp/README.md +155 -0
  77. package/src/utils/mcp/common.js +166 -0
  78. package/src/utils/mcp/manifest.js +382 -0
  79. package/src/utils/mcp/project/server.ts +53 -0
  80. package/src/utils/mcp/project.js +88 -0
  81. package/src/utils/mcp/runtime.js +289 -0
  82. package/src/utils/mcp/schema.js +98 -0
  83. package/src/utils/mcp/workflow-runtime.js +374 -0
  84. package/src/utils/mcp/workflows.js +240 -0
  85. package/src/utils/mcp/zip.js +102 -0
  86. package/src/utils/mcp-generator.js +47 -0
  87. package/src/utils/mock-interceptor.js +557 -0
  88. package/src/utils/oauth-utils.js +87 -0
  89. package/src/utils/request-utils.js +264 -0
  90. package/src/utils/response-utils.js +203 -0
  91. package/src/utils/sanitize.js +57 -0
  92. package/src/utils/schema-utils.js +1954 -0
  93. package/src/utils/slugger.js +187 -0
  94. package/src/utils/spec-parser.js +941 -0
  95. package/src/utils/url-utils.js +246 -0
  96. package/src/utils/xml-utils.js +61 -0
@@ -0,0 +1,603 @@
1
+ import { css, LitElement } from "lit";
2
+ import { customElement, property } from "lit/decorators.js";
3
+ import { scheduleHighlight } from "~/utils/highlighter";
4
+
5
+ // Styles
6
+ import FontStyles from "~/styles/font-styles";
7
+ import InputStyles from "~/styles/input-styles";
8
+ import FlexStyles from "~/styles/flex-styles";
9
+ import AuthStyles from "~/styles/auth-styles";
10
+ import ParamListStyles from "~/styles/param-list-styles";
11
+ import MicrolighterStyles from "~/styles/microlighter-styles";
12
+ import TabStyles from "~/styles/tab-styles";
13
+ import NavStyles from "~/styles/nav-styles";
14
+ import InfoStyles from "~/styles/info-styles";
15
+
16
+ import EndpointStyles from "~/styles/endpoint-styles";
17
+ import ThemeTokens, {
18
+ DEFAULT_THEME,
19
+ applyCustomTheme,
20
+ isValidHexColor,
21
+ normalizeTheme,
22
+ } from "~/styles/theme-tokens";
23
+ import { rapidocApiKey } from "~/utils/common-utils";
24
+ import ProcessSpec from "~/utils/spec-parser";
25
+ import { enableMockServer, disableMockServer, updateMockConfig } from "~/utils/mock-interceptor";
26
+ import mainBodyTemplate from "~/templates/main-body-template";
27
+ import { applyApiKey, onClearAllApiKeys } from "~/templates/security-scheme-template";
28
+ import { setApiServer } from "~/templates/server-template";
29
+ import "~/utils/markdown-utils";
30
+ import { AutoColorSchemeController } from "~/utils/auto-color-scheme";
31
+
32
+ const paramsConverter = {
33
+ fromAttribute: (attr: string | null) => {
34
+ if (!attr) {
35
+ return null;
36
+ }
37
+ const trimmed = attr.trim();
38
+ if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
39
+ try {
40
+ return JSON.parse(trimmed);
41
+ } catch {
42
+ return trimmed;
43
+ }
44
+ }
45
+ return trimmed;
46
+ },
47
+ toAttribute: (prop: any) => {
48
+ if (typeof prop === "object" && prop !== null) {
49
+ return JSON.stringify(prop);
50
+ }
51
+ return prop;
52
+ },
53
+ };
54
+
55
+ @customElement("rapi-doc-mini")
56
+ export default class RapiDocMini extends LitElement {
57
+ // Spec
58
+ @property({ type: String, attribute: "spec-url" }) specUrl = "";
59
+ @property({ type: String, attribute: "sort-endpoints-by" }) sortEndpointsBy = "path";
60
+
61
+ // UI Layouts
62
+ @property({ type: String }) layout = "row";
63
+ @property({ type: String, attribute: "paths-expanded" }) pathsExpanded: any = "false";
64
+ @property({ type: String, attribute: "default-schema-tab" }) defaultSchemaTab = "example";
65
+ @property({ type: String, attribute: "response-area-height" }) responseAreaHeight = "300px";
66
+ @property({ type: String, attribute: "show-summary-when-collapsed" }) showSummaryWhenCollapsed =
67
+ "true";
68
+ @property({ type: String, attribute: "fill-request-fields-with-example" })
69
+ fillRequestFieldsWithExample = "true";
70
+ @property({ type: String, attribute: "persist-auth" }) persistAuth = "false";
71
+
72
+ // Schema Styles
73
+ @property({ type: String, attribute: "schema-style" }) schemaStyle = "tree";
74
+ @property({ type: Number, attribute: "schema-expand-level" }) schemaExpandLevel = 99999;
75
+ @property({ type: String, attribute: "schema-description-expanded" }) schemaDescriptionExpanded =
76
+ "false";
77
+
78
+ // API Server
79
+ @property({ type: String, attribute: "api-key-name" }) apiKeyName = "";
80
+ @property({ type: String, attribute: "api-key-location" }) apiKeyLocation = "header";
81
+ @property({ type: String, attribute: "api-key-value" }) apiKeyValue = "-";
82
+ @property({ type: String, attribute: "default-api-server" }) defaultApiServerUrl = "";
83
+ @property({ type: String, attribute: "server-url" }) serverUrl = "";
84
+ @property({ type: String, attribute: "oauth-receiver" }) oauthReceiver = "oauth-receiver.html";
85
+ @property({ type: Object, attribute: "additional-authorize-params", converter: paramsConverter })
86
+ additionalAuthorizeParams: any;
87
+ @property({ type: Object, attribute: "additional-token-params", converter: paramsConverter })
88
+ additionalTokenParams: any;
89
+
90
+ // Mock Server
91
+ @property({ type: String, attribute: "mock-server" }) mockServer = "false";
92
+ // A string of codes for every operation, or a map by operation (`{ "POST /orders": "503, 200", "*": "200" }`)
93
+ @property({ type: String, attribute: "mock-server-status-code" }) mockServerStatusCode:
94
+ | string
95
+ | Record<string, string> = "200";
96
+ @property({ type: String, attribute: "mock-server-status-strategy" }) mockServerStatusStrategy =
97
+ "example";
98
+ @property({ type: Number, attribute: "mock-server-delay" }) mockServerDelay = 0;
99
+ @property({ type: String, attribute: "mock-server-log" }) mockServerLog = "false";
100
+
101
+ @property({ type: String, attribute: "allow-try" }) allowTry = "true";
102
+ @property({ type: String, attribute: "show-curl-before-try" }) showCurlBeforeTry = "false";
103
+
104
+ // Main Colors and Font
105
+ @property({ type: String, reflect: true }) theme = DEFAULT_THEME;
106
+ @property({ type: String, attribute: "primary-color" }) primaryColor = "";
107
+ @property({ type: String, attribute: "color-scheme", reflect: true }) colorScheme = "dark";
108
+ // color-scheme="auto": follows the page's theme (see utils/auto-color-scheme.js)
109
+ _autoColorScheme = new AutoColorSchemeController(this);
110
+ @property({ type: String, reflect: true }) radius = "sm";
111
+ @property({ type: String, reflect: true }) scale = "default";
112
+
113
+ // Fetch Options
114
+ @property({ type: String, attribute: "fetch-credentials" }) fetchCredentials = "";
115
+
116
+ // Filters
117
+ @property({ type: String, attribute: "match-paths" }) matchPaths = "";
118
+ @property({ type: String, attribute: "match-type" }) matchType = "includes";
119
+ @property({ type: String, attribute: "remove-endpoints-with-badge-label-as" })
120
+ removeEndpointsWithBadgeLabelAs = "";
121
+
122
+ // Internal Properties
123
+ @property({ type: Boolean }) loading = false;
124
+
125
+ isMini: boolean;
126
+ _specLoadSeq: number;
127
+ updateRoute: string;
128
+ renderStyle: string;
129
+ showHeader: string;
130
+ allowAdvancedSearch: string;
131
+ resolvedSpec: any;
132
+ selectedServer: any;
133
+ loadFailed: boolean;
134
+ sortTags: any;
135
+ generateMissingTags: any;
136
+ sortSchemas: any;
137
+ allowSchemaDescriptionExpandToggle: any;
138
+
139
+ constructor() {
140
+ super();
141
+ this.isMini = true;
142
+ // Spec loads carry a token; only the latest load may apply its result (see loadSpec)
143
+ this._specLoadSeq = 0;
144
+ this.updateRoute = "false";
145
+ this.renderStyle = "view";
146
+ this.showHeader = "false";
147
+ this.allowAdvancedSearch = "false";
148
+ this.loadFailed = false;
149
+ }
150
+
151
+ static get styles() {
152
+ return [
153
+ ThemeTokens,
154
+ FontStyles,
155
+ InputStyles,
156
+ FlexStyles,
157
+ AuthStyles,
158
+ ParamListStyles,
159
+ EndpointStyles,
160
+ MicrolighterStyles,
161
+ TabStyles,
162
+ NavStyles,
163
+ InfoStyles,
164
+ css`
165
+ :host {
166
+ all: initial;
167
+ /* Same crisp text rendering as <rapi-doc> (see layout-styles.js) */
168
+ -webkit-font-smoothing: antialiased;
169
+ -moz-osx-font-smoothing: grayscale;
170
+ display: flex;
171
+ flex-direction: column;
172
+ min-width: 360px;
173
+ width: 100%;
174
+ height: 100%;
175
+ margin: 0;
176
+ padding: 0;
177
+ overflow: hidden;
178
+ letter-spacing: normal;
179
+ color: var(--foreground);
180
+ background: var(--background);
181
+ font-family: var(--font-sans);
182
+ container-type: inline-size;
183
+ }
184
+
185
+ @container (min-width: 768px) {
186
+ .only-large-screen {
187
+ display: block;
188
+ }
189
+ .only-large-screen-flex {
190
+ display: flex;
191
+ }
192
+ }
193
+ `,
194
+ ];
195
+ }
196
+
197
+ // Startup
198
+ connectedCallback() {
199
+ super.connectedCallback();
200
+
201
+ if (
202
+ !this.showSummaryWhenCollapsed ||
203
+ !"true, false,".includes(`${this.showSummaryWhenCollapsed},`)
204
+ ) {
205
+ this.showSummaryWhenCollapsed = "true";
206
+ }
207
+ if (!this.layout || !"row, column,".includes(`${this.layout},`)) {
208
+ this.layout = "row";
209
+ }
210
+ if (!this.schemaStyle || !"tree, table,".includes(`${this.schemaStyle},`)) {
211
+ this.schemaStyle = "tree";
212
+ }
213
+ if (this.primaryColor && isValidHexColor(this.primaryColor)) {
214
+ this.theme = this.primaryColor;
215
+ }
216
+ const normalizedTheme = normalizeTheme(this.theme);
217
+ this.theme = normalizedTheme.theme;
218
+ this.setAttribute("theme", this.theme);
219
+ if (!this.colorScheme || !"dark, light, system,".includes(`${this.colorScheme},`)) {
220
+ this.colorScheme = "dark";
221
+ }
222
+ if (!this.radius || !"none, sm, md, lg, full,".includes(`${this.radius},`)) {
223
+ this.radius = "sm";
224
+ }
225
+ if (!this.scale || !"sm, default, lg,".includes(`${this.scale},`)) {
226
+ this.scale = "default";
227
+ }
228
+ if (!this.getAttribute("theme")) {
229
+ this.setAttribute("theme", this.theme);
230
+ }
231
+ if (!this.getAttribute("color-scheme")) {
232
+ this.setAttribute("color-scheme", this.colorScheme);
233
+ }
234
+ if (!this.getAttribute("radius")) {
235
+ this.setAttribute("radius", this.radius);
236
+ }
237
+ if (!this.getAttribute("scale")) {
238
+ this.setAttribute("scale", this.scale);
239
+ }
240
+ applyCustomTheme(this, this.theme);
241
+ if (
242
+ !this.defaultSchemaTab ||
243
+ !"example, schema, model,".includes(`${this.defaultSchemaTab},`)
244
+ ) {
245
+ this.defaultSchemaTab = "example";
246
+ } else if (this.defaultSchemaTab === "model") {
247
+ this.defaultSchemaTab = "schema";
248
+ }
249
+ this.pathsExpanded = this.pathsExpanded === "true";
250
+ if (!this.schemaExpandLevel || this.schemaExpandLevel < 1) {
251
+ this.schemaExpandLevel = 99999;
252
+ }
253
+ if (
254
+ !this.schemaDescriptionExpanded ||
255
+ !"true, false,".includes(`${this.schemaDescriptionExpanded},`)
256
+ ) {
257
+ this.schemaDescriptionExpanded = "false";
258
+ }
259
+ if (
260
+ !this.fillRequestFieldsWithExample ||
261
+ !"true, false,".includes(`${this.fillRequestFieldsWithExample},`)
262
+ ) {
263
+ this.fillRequestFieldsWithExample = "true";
264
+ }
265
+ if (!this.persistAuth || !"true, false,".includes(`${this.persistAuth},`)) {
266
+ this.persistAuth = "false";
267
+ }
268
+ if (!this.responseAreaHeight) {
269
+ this.responseAreaHeight = "300px";
270
+ }
271
+
272
+ if (!this.allowTry || !"true, false,".includes(`${this.allowTry},`)) {
273
+ this.allowTry = "true";
274
+ }
275
+ if (!this.apiKeyValue) {
276
+ this.apiKeyValue = "-";
277
+ }
278
+ if (!this.apiKeyLocation) {
279
+ this.apiKeyLocation = "header";
280
+ }
281
+ if (!this.apiKeyName) {
282
+ this.apiKeyName = "";
283
+ }
284
+
285
+ if (!this.oauthReceiver) {
286
+ this.oauthReceiver = "oauth-receiver.html";
287
+ }
288
+ if (!this.sortTags || !"true, false,".includes(`${this.sortTags},`)) {
289
+ this.sortTags = "false";
290
+ }
291
+ if (!this.sortEndpointsBy || !"method, path, summary,".includes(`${this.sortEndpointsBy},`)) {
292
+ this.sortEndpointsBy = "path";
293
+ }
294
+
295
+ if (!this.matchType || !"includes regex".includes(this.matchType)) {
296
+ this.matchType = "includes";
297
+ }
298
+ if (!this.matchPaths) {
299
+ this.matchPaths = "";
300
+ }
301
+ if (!this.removeEndpointsWithBadgeLabelAs) {
302
+ this.removeEndpointsWithBadgeLabelAs = "";
303
+ }
304
+
305
+ if (
306
+ !this.allowSchemaDescriptionExpandToggle ||
307
+ !"true, false,".includes(`${this.allowSchemaDescriptionExpandToggle},`)
308
+ ) {
309
+ this.allowSchemaDescriptionExpandToggle = "true";
310
+ }
311
+ if (
312
+ !this.fetchCredentials ||
313
+ !"omit, same-origin, include,".includes(`${this.fetchCredentials},`)
314
+ ) {
315
+ this.fetchCredentials = "";
316
+ }
317
+ }
318
+
319
+ disconnectedCallback() {
320
+ if (this.mockServer === "true") {
321
+ disableMockServer(this);
322
+ }
323
+ super.disconnectedCallback();
324
+ }
325
+
326
+ render() {
327
+ return mainBodyTemplate.call(this, true, this.pathsExpanded);
328
+ }
329
+
330
+ get config() {
331
+ return {
332
+ renderStyle: this.renderStyle,
333
+ schemaStyle: this.schemaStyle,
334
+ defaultSchemaTab: this.defaultSchemaTab,
335
+ schemaExpandLevel: this.schemaExpandLevel,
336
+ schemaDescriptionExpanded: this.schemaDescriptionExpanded,
337
+ allowSchemaDescriptionExpandToggle: this.allowSchemaDescriptionExpandToggle,
338
+ schemaHideReadOnly: this.schemaHideReadOnly,
339
+ schemaHideWriteOnly: this.schemaHideWriteOnly,
340
+ fillRequestFieldsWithExample: this.fillRequestFieldsWithExample,
341
+ allowTry: this.allowTry,
342
+ showCurlBeforeTry: this.showCurlBeforeTry,
343
+ fetchCredentials: this.fetchCredentials,
344
+ };
345
+ }
346
+
347
+ updated(changedProperties) {
348
+ super.updated?.(changedProperties);
349
+ scheduleHighlight(this.shadowRoot);
350
+
351
+ if (changedProperties.has("theme")) {
352
+ const normalizedTheme = normalizeTheme(this.theme);
353
+ if (this.theme !== normalizedTheme.theme) {
354
+ this.theme = normalizedTheme.theme;
355
+ this.setAttribute("theme", this.theme);
356
+ }
357
+ applyCustomTheme(this, this.theme);
358
+ }
359
+
360
+ if (
361
+ changedProperties.has("primaryColor") &&
362
+ this.primaryColor &&
363
+ isValidHexColor(this.primaryColor)
364
+ ) {
365
+ this.theme = normalizeTheme(this.primaryColor).theme;
366
+ this.setAttribute("theme", this.theme);
367
+ applyCustomTheme(this, this.theme);
368
+ }
369
+
370
+ if (changedProperties.has("mockServer")) {
371
+ if (this.mockServer === "true" && this.resolvedSpec) {
372
+ enableMockServer(this.resolvedSpec, {
373
+ owner: this,
374
+ statusCode: this.mockServerStatusCode,
375
+ statusStrategy: this.mockServerStatusStrategy,
376
+ delay: this.mockServerDelay,
377
+ log: this.mockServerLog,
378
+ });
379
+ } else if (this.mockServer !== "true") {
380
+ disableMockServer(this);
381
+ }
382
+ }
383
+ if (
384
+ changedProperties.has("mockServerStatusCode") ||
385
+ changedProperties.has("mockServerStatusStrategy") ||
386
+ changedProperties.has("mockServerDelay") ||
387
+ changedProperties.has("mockServerLog")
388
+ ) {
389
+ updateMockConfig({
390
+ owner: this,
391
+ statusCode: this.mockServerStatusCode,
392
+ statusStrategy: this.mockServerStatusStrategy,
393
+ delay: this.mockServerDelay,
394
+ log: this.mockServerLog,
395
+ });
396
+ }
397
+ }
398
+
399
+ attributeChangedCallback(name, oldVal, newVal) {
400
+ if (name === "spec-url") {
401
+ if (oldVal !== newVal) {
402
+ // put it at the end of event-loop to load all the attributes
403
+ window.setTimeout(async () => {
404
+ await this.loadSpec(newVal);
405
+ }, 0);
406
+ }
407
+ }
408
+ if (
409
+ name === "match-paths" ||
410
+ name === "match-type" ||
411
+ name === "remove-endpoints-with-badge-label-as"
412
+ ) {
413
+ if (oldVal !== newVal) {
414
+ window.setTimeout(async () => {
415
+ await this.loadSpec(this.specUrl);
416
+ }, 0);
417
+ }
418
+ }
419
+ if (name === "api-key-name" || name === "api-key-location" || name === "api-key-value") {
420
+ let updateSelectedApiKey = false;
421
+ let apiKeyName = "";
422
+ let apiKeyLocation = "";
423
+ let apiKeyValue = "";
424
+
425
+ if (name === "api-key-name") {
426
+ if (this.getAttribute("api-key-location") && this.getAttribute("api-key-value")) {
427
+ apiKeyName = newVal;
428
+ apiKeyLocation = this.getAttribute("api-key-location");
429
+ apiKeyValue = this.getAttribute("api-key-value");
430
+ updateSelectedApiKey = true;
431
+ }
432
+ } else if (name === "api-key-location") {
433
+ if (this.getAttribute("api-key-name") && this.getAttribute("api-key-value")) {
434
+ apiKeyLocation = newVal;
435
+ apiKeyName = this.getAttribute("api-key-name");
436
+ apiKeyValue = this.getAttribute("api-key-value");
437
+ updateSelectedApiKey = true;
438
+ }
439
+ } else if (name === "api-key-value") {
440
+ if (this.getAttribute("api-key-name") && this.getAttribute("api-key-location")) {
441
+ apiKeyValue = newVal;
442
+ apiKeyLocation = this.getAttribute("api-key-location");
443
+ apiKeyName = this.getAttribute("api-key-name");
444
+ updateSelectedApiKey = true;
445
+ }
446
+ }
447
+
448
+ if (updateSelectedApiKey) {
449
+ // While the spec is loading, resolvedSpec is a placeholder without securitySchemes
450
+ if (this.resolvedSpec?.securitySchemes) {
451
+ const rapiDocApiKey = this.resolvedSpec.securitySchemes.find(
452
+ (v: any) => v.securitySchemeId === rapidocApiKey,
453
+ );
454
+ if (!rapiDocApiKey) {
455
+ this.resolvedSpec.securitySchemes.push({
456
+ securitySchemeId: rapidocApiKey,
457
+ description: "api-key provided in rapidoc element attributes",
458
+ type: "apiKey",
459
+ name: apiKeyName,
460
+ in: apiKeyLocation,
461
+ value: apiKeyValue,
462
+ finalKeyValue: apiKeyValue,
463
+ });
464
+ } else {
465
+ rapiDocApiKey.name = apiKeyName;
466
+ rapiDocApiKey.in = apiKeyLocation;
467
+ rapiDocApiKey.value = apiKeyValue;
468
+ rapiDocApiKey.finalKeyValue = apiKeyValue;
469
+ }
470
+ this.requestUpdate();
471
+ }
472
+ }
473
+ }
474
+ super.attributeChangedCallback(name, oldVal, newVal);
475
+ }
476
+
477
+ onSpecUrlChange() {
478
+ this.setAttribute("spec-url", (this.shadowRoot.getElementById("spec-url") as any).value);
479
+ }
480
+
481
+ // Public Method
482
+ async loadSpec(specUrl) {
483
+ if (!specUrl) {
484
+ return;
485
+ }
486
+ // Each load gets a token; a load whose token is no longer current never applies its result
487
+ const token = ++this._specLoadSeq;
488
+ try {
489
+ this.resolvedSpec = {
490
+ specLoadError: false,
491
+ isSpecLoading: true,
492
+ tags: [],
493
+ };
494
+ this.loading = true;
495
+ this.loadFailed = false;
496
+ this.requestUpdate();
497
+ const spec = await ProcessSpec.call(
498
+ this,
499
+ specUrl,
500
+ this.generateMissingTags === "true",
501
+ this.sortTags === "true",
502
+ this.sortSchemas === "true",
503
+ this.getAttribute("sort-endpoints-by"),
504
+ this.getAttribute("api-key-name"),
505
+ this.getAttribute("api-key-location"),
506
+ this.getAttribute("api-key-value"),
507
+ this.getAttribute("server-url"),
508
+ this.matchPaths,
509
+ this.matchType,
510
+ this.removeEndpointsWithBadgeLabelAs,
511
+ );
512
+ if (token !== this._specLoadSeq) {
513
+ return; // a newer load started while this one was parsing
514
+ }
515
+ this.loading = false;
516
+ this.afterSpecParsedAndValidated(spec, token);
517
+ } catch (err: any) {
518
+ if (token !== this._specLoadSeq) {
519
+ return;
520
+ }
521
+ this.loading = false;
522
+ this.loadFailed = true;
523
+ this.resolvedSpec = null;
524
+ console.error(`RapiDoc: Unable to resolve the API spec.. ${err.message}`);
525
+ }
526
+ }
527
+
528
+ // Public Method - to update security-scheme of type http
529
+ setHttpUserNameAndPassword(securitySchemeId, username, password) {
530
+ return applyApiKey.call(this, securitySchemeId, username, password);
531
+ }
532
+
533
+ // Public Method - to update security-scheme of type apiKey or OAuth.
534
+ // options.note: where the key came from (e.g. "Using your sign-in"), shown in place of the scheme's form
535
+ setApiKey(securitySchemeId, apiKeyValue, options: { note?: string } = {}) {
536
+ return applyApiKey.call(this, securitySchemeId, "", "", apiKeyValue, options?.note || "");
537
+ }
538
+
539
+ // Public Method
540
+ removeAllSecurityKeys() {
541
+ return onClearAllApiKeys.call(this);
542
+ }
543
+
544
+ // Public Method
545
+ setApiServer(apiServerUrl) {
546
+ // return apiServerUrl;
547
+ return setApiServer.call(this, apiServerUrl);
548
+ }
549
+
550
+ async afterSpecParsedAndValidated(spec, token = this._specLoadSeq) {
551
+ this.resolvedSpec = spec;
552
+ this.selectedServer = undefined;
553
+ if (this.defaultApiServerUrl) {
554
+ if (this.defaultApiServerUrl === this.serverUrl) {
555
+ this.selectedServer = {
556
+ url: this.serverUrl,
557
+ computedUrl: this.serverUrl,
558
+ };
559
+ } else if (this.resolvedSpec.servers) {
560
+ this.selectedServer = this.resolvedSpec.servers.find(
561
+ (v: any) => v.url === this.defaultApiServerUrl,
562
+ );
563
+ }
564
+ }
565
+ if (!this.selectedServer) {
566
+ if (this.resolvedSpec.servers) {
567
+ this.selectedServer = this.resolvedSpec.servers[0];
568
+ }
569
+ }
570
+ this.requestUpdate();
571
+
572
+ while (!(await this.updateComplete));
573
+ if (token !== this._specLoadSeq) {
574
+ return; // a newer load took over while this one was rendering; it fires its own spec-loaded
575
+ }
576
+ const specLoadedEvent = new CustomEvent("spec-loaded", { detail: spec });
577
+ this.dispatchEvent(specLoadedEvent);
578
+
579
+ if (this.mockServer === "true") {
580
+ enableMockServer(this.resolvedSpec, {
581
+ owner: this,
582
+ statusCode: this.mockServerStatusCode,
583
+ statusStrategy: this.mockServerStatusStrategy,
584
+ delay: this.mockServerDelay,
585
+ log: this.mockServerLog,
586
+ });
587
+ }
588
+ }
589
+
590
+ // Called by anchor tags created using markdown
591
+ handleHref(e) {
592
+ if (e.target.tagName.toLowerCase() === "a") {
593
+ if (e.target.getAttribute("href").startsWith("#")) {
594
+ const gotoEl = this.shadowRoot.getElementById(
595
+ e.target.getAttribute("href").replace("#", ""),
596
+ );
597
+ if (gotoEl) {
598
+ gotoEl.scrollIntoView({ behavior: "auto", block: "start" });
599
+ }
600
+ }
601
+ }
602
+ }
603
+ }