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,146 @@
1
+ /**
2
+ * Renders the single active API operation, overview, or component in focused (3-column) rendering mode.
3
+ */
4
+ import { fixRenderedAnchorLinks } from "~/utils/markdown-utils";
5
+ import { html } from "lit";
6
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
7
+ import { sanitizeHTML } from "../utils/sanitize.js";
8
+ import { marked } from "marked";
9
+ import Slugger from "github-slugger";
10
+ import { expandedEndpointBodyTemplate } from "~/templates/expanded-endpoint-template";
11
+ import "~/components/api-request";
12
+ import "~/components/api-response";
13
+ import componentsTemplate from "~/templates/components-template";
14
+ import overviewTemplate from "~/templates/overview-template";
15
+ import downloadsTemplate from "~/templates/downloads-template";
16
+ import serverTemplate from "~/templates/server-template";
17
+ import securitySchemeTemplate from "~/templates/security-scheme-template";
18
+ import { expandCollapseNavBarTag } from "~/templates/navbar-template";
19
+
20
+ function headingRenderer(tagElementId) {
21
+ const renderer = new marked.Renderer();
22
+ const slugger = new Slugger();
23
+ // renderer.heading = (text, level, raw, slugger) => `<h${level} class="observe-me" id="${tagElementId}--${slugger.slug(raw)}">${text}</h${level}>`;
24
+ renderer.heading = ({ text, depth }) =>
25
+ `<h${depth} class="observe-me" id="${tagElementId}--${slugger.slug(text)}">${text}</h${depth}>`;
26
+ fixRenderedAnchorLinks(renderer);
27
+ return renderer;
28
+ }
29
+
30
+ function wrapFocusedTemplate(templateToWrap) {
31
+ return html`<div class="regular-font section-gap--focused-mode" part="section-operations-in-tag">${templateToWrap}</div>`;
32
+ }
33
+
34
+ function defaultContentTemplate() {
35
+ // In focused mode default content is overview or first path
36
+ if (this.showInfo === "true") {
37
+ return wrapFocusedTemplate(html`${overviewTemplate.call(this)}${downloadsTemplate.call(this)}`);
38
+ }
39
+ // the first tag with operations: a description-only tag (show-unused-tags) has none
40
+ const selectedTagObj = this.resolvedSpec.tags.find((t) => t.paths.length > 0);
41
+ const selectedPathObj = selectedTagObj?.paths[0];
42
+ return selectedTagObj && selectedPathObj
43
+ ? wrapFocusedTemplate(
44
+ expandedEndpointBodyTemplate.call(
45
+ this,
46
+ selectedPathObj,
47
+ selectedTagObj.name || "",
48
+ selectedTagObj.description || "",
49
+ true,
50
+ ),
51
+ )
52
+ : wrapFocusedTemplate("");
53
+ }
54
+
55
+ function focusedTagBodyTemplate(tag) {
56
+ return html`
57
+ <h2 id="${tag.elementId}" class="rapidoc-heading title tag" part="section-tag-title label-tag-title heading heading-2">
58
+ ${tag.displayName || tag.name}
59
+ </h2>
60
+ ${
61
+ tag.description
62
+ ? html`<div class="m-markdown regular-font">
63
+ ${unsafeHTML(
64
+ sanitizeHTML(
65
+ marked(
66
+ tag.description || "",
67
+ this.infoDescriptionHeadingsInNavBar === "true"
68
+ ? { renderer: headingRenderer(tag.elementId) }
69
+ : undefined,
70
+ ),
71
+ ),
72
+ )}
73
+ </div>`
74
+ : ""
75
+ }
76
+ `;
77
+ }
78
+
79
+ export default function focusedEndpointTemplate() {
80
+ if (!this.focusedElementId && this.resolvedSpec) {
81
+ this.focusedElementId =
82
+ this.showInfo === "false" || this.showInfo === false
83
+ ? this.resolvedSpec.tags?.find((t) => t.paths.length > 0)?.paths[0]?.elementId || ""
84
+ : "overview";
85
+ }
86
+ if (!this.focusedElementId || !this.resolvedSpec) {
87
+ return;
88
+ }
89
+ const focusElId = this.focusedElementId;
90
+ let selectedPathObj = null;
91
+ let selectedTagObj = null;
92
+ let focusedTemplate;
93
+ if (focusElId.startsWith("overview") && this.showInfo === "true") {
94
+ focusedTemplate = html`${overviewTemplate.call(this)}${downloadsTemplate.call(this)}`;
95
+ } else if (focusElId === "auth" && this.allowAuthentication === "true") {
96
+ focusedTemplate = securitySchemeTemplate.call(this, this.allowTry);
97
+ } else if (focusElId === "servers" && this.allowServerSelection === "true") {
98
+ focusedTemplate = serverTemplate.call(this);
99
+ } else if (focusElId === "operations-top") {
100
+ focusedTemplate = html`<div id="operations-top" class="observe-me"><slot name="operations-top"></slot></div>`;
101
+ } else if (focusElId.startsWith("cmp--") && this.showComponents === "true") {
102
+ focusedTemplate = componentsTemplate.call(this);
103
+ } else if (focusElId.startsWith("tag--")) {
104
+ const idToFocus =
105
+ focusElId.indexOf("--", 4) > 0
106
+ ? focusElId.substring(0, focusElId.indexOf("--", 5))
107
+ : focusElId;
108
+ selectedTagObj = this.resolvedSpec.tags.find((v) => v.elementId === idToFocus);
109
+ if (selectedTagObj) {
110
+ focusedTemplate = wrapFocusedTemplate.call(
111
+ this,
112
+ focusedTagBodyTemplate.call(this, selectedTagObj),
113
+ );
114
+ } else {
115
+ focusedTemplate = defaultContentTemplate.call(this);
116
+ }
117
+ } else {
118
+ for (const tag of this.resolvedSpec.tags) {
119
+ selectedTagObj = tag;
120
+ selectedPathObj = tag.paths.find((v) => `${v.elementId}` === focusElId);
121
+ if (selectedPathObj) {
122
+ break;
123
+ }
124
+ }
125
+ if (selectedPathObj) {
126
+ // In focused mode we must expand the nav-bar tag element if it is collapsed
127
+ const newNavEl = this.shadowRoot?.getElementById(`link-${focusElId}`); // no shadowRoot when pre-rendering
128
+ expandCollapseNavBarTag(newNavEl, "expand");
129
+ const isFirst = selectedTagObj?.paths?.[0]?.elementId === selectedPathObj.elementId;
130
+ focusedTemplate = wrapFocusedTemplate.call(
131
+ this,
132
+ expandedEndpointBodyTemplate.call(
133
+ this,
134
+ selectedPathObj,
135
+ selectedTagObj.name || "",
136
+ selectedTagObj.description || "",
137
+ isFirst,
138
+ ),
139
+ );
140
+ } else {
141
+ // if focusedElementId is not found then show the default content (overview or first-path)
142
+ focusedTemplate = defaultContentTemplate.call(this);
143
+ }
144
+ }
145
+ return focusedTemplate;
146
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Renders the top navigation header with logo, title, search trigger, server selector, theme switcher, and auth controls.
3
+ */
4
+ import { html } from "lit";
5
+ import logoTemplate from "~/templates/logo-template";
6
+
7
+ export default function headerTemplate() {
8
+ return html`<header class="row main-header regular-font" part="section-header">
9
+ <div class="only-large-screen-flex" style="align-items: center;">
10
+ <slot name="logo" class="logo" part="section-logo">
11
+ ${logoTemplate("height:36px;width:36px;margin-left:5px")}
12
+ <!-- m-logo style="height:36px;width:36px;margin-left:5px"></m-logo -->
13
+ </slot>
14
+ <div class="header-title" part="label-header-title">${this.headingText}</div>
15
+ </div>
16
+ <div class="main-header-controls">
17
+ ${
18
+ this.allowSpecUrlLoad === "false"
19
+ ? ""
20
+ : html`
21
+ <input
22
+ id="spec-url"
23
+ type="text"
24
+ style="font-size:var(--font-size-small)"
25
+ class="header-input mono-font"
26
+ part="textbox textbox-spec-url"
27
+ placeholder="Spec URL"
28
+ value="${this.specUrl || ""}"
29
+ @change="${this.onSpecUrlChange}"
30
+ spellcheck="false"
31
+ />
32
+ <div class="header-action-icon" @click="${this.onSpecUrlChange}">&#x21a9;</div>
33
+ `
34
+ }
35
+ ${
36
+ this.allowSpecFileLoad === "false"
37
+ ? ""
38
+ : html`
39
+ <input
40
+ id="spec-file"
41
+ part="file-input"
42
+ type="file"
43
+ style="display:none"
44
+ value="${this.specFile || ""}"
45
+ @change="${this.onSpecFileChange}"
46
+ spellcheck="false"
47
+ />
48
+ <button
49
+ class="btn btn-primary only-large-screen"
50
+ style="margin-left:10px;"
51
+ part="btn btn-fill"
52
+ @click="${this.onFileLoadClick}"
53
+ >
54
+ LOCAL JSON FILE
55
+ </button>
56
+ `
57
+ }
58
+ <slot name="header"></slot>
59
+ ${
60
+ this.allowSearch === "false" || "read focused".includes(this.renderStyle)
61
+ ? ""
62
+ : html`
63
+ <input
64
+ id="search"
65
+ class="header-input"
66
+ type="text"
67
+ part="textbox textbox-header-filter"
68
+ placeholder="Filter"
69
+ @change="${this.onSearchChange}"
70
+ style="max-width:130px;margin-left:10px;"
71
+ spellcheck="false"
72
+ />
73
+ <div class="header-action-icon" @click="${this.onSearchChange}">&#x21a9;</div>
74
+ `
75
+ }
76
+ ${
77
+ this.allowAdvancedSearch === "false" || "read focused".includes(this.renderStyle)
78
+ ? ""
79
+ : html`
80
+ <button
81
+ class="btn btn-primary only-large-screen"
82
+ part="btn btn-fill btn-search"
83
+ style="margin-left:10px;"
84
+ @click="${this.onShowAdvancedSearchClicked}"
85
+ >
86
+ Search
87
+ </button>
88
+ `
89
+ }
90
+ </div>
91
+ </header>`;
92
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Renders default RapiDoc SVG branding logo.
3
+ */
4
+ import { html } from "lit";
5
+
6
+ export default function logoTemplate(style) {
7
+ return html`<svg style=${style} viewBox="1 0 511 512">
8
+ <path d="M351 411a202 202 0 01-350 0 203 203 0 01333-24 203 203 0 0117 24zm0 0" fill="#adc165" />
9
+ <path
10
+ d="M334 387a202 202 0 01-216-69 202 202 0 01216 69zm78 32H85a8 8 0 01-8-8 8 8 0 018-8h327a8 8 0 017 8 8 8 0 01-7 8zm0 0"
11
+ fill="#99aa52"
12
+ />
13
+ <path d="M374 338l-5 30a202 202 0 01-248-248 203 203 0 01253 218zm0 0" fill="#ffc73b" />
14
+ <path
15
+ d="M374 338a202 202 0 01-100-197 203 203 0 01100 197zm38 81l-6-2-231-231a8 8 0 0111-11l231 230a8 8 0 01-5 14zm0 0"
16
+ fill="#efb025"
17
+ />
18
+ <path d="M311 175c0 75 40 140 101 175a202 202 0 000-350 202 202 0 00-101 175zm0 0" fill="#ff903e" />
19
+ <path d="M412 419a8 8 0 01-8-8V85a8 8 0 0115 0v326a8 8 0 01-7 8zm0 0" fill="#e87425" />
20
+ </svg>`;
21
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Renders the top-level main layout shell, orchestrating header, navbar, content panels, and modal dialogs based on renderStyle.
3
+ */
4
+ import { html } from "lit";
5
+
6
+ // Templates
7
+ import expandedEndpointTemplate from "~/templates/expanded-endpoint-template";
8
+ import focusedEndpointTemplate from "~/templates/focused-endpoint-template";
9
+ import overviewTemplate from "~/templates/overview-template";
10
+ import endpointTemplate from "~/templates/endpoint-template";
11
+ import serverTemplate from "~/templates/server-template";
12
+ import securitySchemeTemplate, {
13
+ recoverPersistedApiKeys,
14
+ } from "~/templates/security-scheme-template";
15
+ import headerTemplate from "~/templates/header-template";
16
+ import navbarTemplate from "~/templates/navbar-template";
17
+ import advancedSearchDialogTemplate from "~/templates/advanced-search-dialog-template";
18
+ import componentsTemplate from "~/templates/components-template";
19
+ import downloadsTemplate from "~/templates/downloads-template";
20
+
21
+ export default function mainBodyTemplate(isMini = false, pathsExpanded = false) {
22
+ if (!this.resolvedSpec) {
23
+ return "";
24
+ }
25
+ if (this.persistAuth === "true") {
26
+ recoverPersistedApiKeys.call(this);
27
+ }
28
+
29
+ if (this.resolvedSpec.specLoadError) {
30
+ return html` <div id="spec-not-found">${this.resolvedSpec.info.description}</div>`;
31
+ }
32
+
33
+ if (this.resolvedSpec.isSpecLoading) {
34
+ return html` <main class="main-content regular-font" part="section-main-content">
35
+ <slot></slot>
36
+ <div class="main-content-inner--${this.renderStyle}-mode">
37
+ <div class="loader"></div>
38
+ </div>
39
+ </main>`;
40
+ }
41
+
42
+ return html` <slot name="fixed-header"></slot>
43
+ <!-- Header -->
44
+ ${this.showHeader === "false" ? "" : headerTemplate.call(this)}
45
+
46
+ <!-- Advanced Search -->
47
+ ${this.allowAdvancedSearch === "false" ? "" : advancedSearchDialogTemplate.call(this)}
48
+
49
+ <div id="the-main-body" class="body ${this.cssClasses}" dir="${this.pageDirection}">
50
+ <!-- Side Nav -->
51
+ ${
52
+ (this.renderStyle === "read" || this.renderStyle === "focused") &&
53
+ this.showSideNav === "true" &&
54
+ this.resolvedSpec
55
+ ? navbarTemplate.call(this)
56
+ : ""
57
+ }
58
+
59
+ <!-- Main Content -->
60
+ <main class="main-content regular-font" tabindex="-1" part="section-main-content">
61
+ <slot></slot>
62
+ <div class="main-content-inner--${this.renderStyle}-mode">
63
+ ${
64
+ this.loading === true
65
+ ? html`<div class="loader"></div>`
66
+ : html` ${
67
+ this.loadFailed === true
68
+ ? html`<div style="text-align: center;margin: 16px;">Unable to load the Spec</div>`
69
+ : html`
70
+ <div
71
+ class="operations-root"
72
+ @click="${(e) => {
73
+ this.handleHref(e);
74
+ }}"
75
+ >
76
+ ${
77
+ this.renderStyle === "focused"
78
+ ? html`${this.showInfo === "false" ? downloadsTemplate.call(this) : ""}${focusedEndpointTemplate.call(this)}`
79
+ : html`
80
+ ${this.showInfo === "true" ? overviewTemplate.call(this) : ""} ${downloadsTemplate.call(this)}
81
+ ${this.allowServerSelection === "true" ? serverTemplate.call(this) : ""}
82
+ ${this.allowAuthentication === "true" ? securitySchemeTemplate.call(this, this.allowTry) : ""}
83
+ <div id="operations-top" class="observe-me">
84
+ <slot name="operations-top"></slot>
85
+ </div>
86
+ ${
87
+ this.renderStyle === "read"
88
+ ? expandedEndpointTemplate.call(this)
89
+ : endpointTemplate.call(this, isMini, pathsExpanded)
90
+ }
91
+ ${this.showComponents === "true" ? componentsTemplate.call(this) : ""}
92
+ `
93
+ }
94
+ </div>
95
+ `
96
+ }`
97
+ }
98
+ </div>
99
+ <slot name="footer"></slot>
100
+ </main>
101
+ </div>`;
102
+ }