Skip to content

Commit dfc7b07

Browse files
authored
fix: various OpenAPI plugin fixes (#1371)
- fix HTML comments in descriptions - group sidebar based on group tags - enable redirects for redoc links (`#tag...`) - scroll sidebar after redirect - enable redirects for sidebar categories - fix wrongly escaped inline code block - redirect to search page if no match found
1 parent 3374f47 commit dfc7b07

File tree

10 files changed

+322
-47
lines changed

10 files changed

+322
-47
lines changed

apify-api/openapi/openapi.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ info:
4545
4646
To use your token in a request, either:
4747
48-
- Add the token to your request's `Authorization` header as `Bearer
49-
<token>`.
48+
- Add the token to your request's `Authorization` header as `Bearer <token>`.
5049
E.g., `Authorization: Bearer xxxxxxx`.
5150
[More info](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization).
5251
(Recommended).

apify-api/openapi/paths/actors/acts@{actorId}@run-sync.yaml

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,22 @@ post:
55
description: |
66
Runs a specific Actor and returns its output.
77
8-
98
The POST payload including its `Content-Type` header is passed as `INPUT` to
109
the Actor (usually <code>application/json</code>).
11-
1210
The HTTP response contains Actors `OUTPUT` record from its default
1311
key-value store.
1412
15-
1613
The Actor is started with the default options; you can override them using
1714
various URL query parameters.
18-
1915
If the Actor run exceeds 300<!-- MAX_ACTOR_JOB_SYNC_WAIT_SECS --> seconds,
2016
the HTTP response will have status 408 (Request Timeout).
2117
22-
2318
Beware that it might be impossible to maintain an idle HTTP connection for a
2419
long period of time, due to client timeout or network conditions. Make sure your HTTP client is
2520
configured to have a long enough connection timeout.
26-
2721
If the connection breaks, you will not receive any information about the run
2822
and its status.
2923
30-
3124
To run the Actor asynchronously, use the [Run
3225
Actor](#/reference/actors/run-collection/run-actor) API endpoint instead.
3326
operationId: act_runSync_post
@@ -42,9 +35,9 @@ post:
4235
example: janedoe~my-actor
4336
- name: outputRecordKey
4437
in: query
45-
description: |-
38+
description: |
4639
Key of the record from run's default key-value store to be returned
47-
in the response. By default, it is `OUTPUT`.
40+
in the response. By default, it is `OUTPUT`.
4841
style: form
4942
explode: true
5043
schema:
@@ -103,12 +96,9 @@ post:
10396
description: |
10497
Specifies optional webhooks associated with the Actor run, which can be
10598
used to receive a notification
106-
10799
e.g. when the Actor finished or failed. The value is a Base64-encoded
108100
JSON array of objects defining the webhooks. For more information, see
109-
110-
[Webhooks
111-
documentation](https://docs.apify.com/platform/integrations/webhooks).
101+
[Webhooks documentation](https://docs.apify.com/platform/integrations/webhooks).
112102
style: form
113103
explode: true
114104
schema:
@@ -143,9 +133,8 @@ post:
143133
example:
144134
error:
145135
type: run-failed
146-
message: >-
147-
Actor run did not succeed (run ID: 55uatRrZib4xbZs, status:
148-
FAILED)
136+
message: |
137+
Actor run did not succeed (run ID: 55uatRrZib4xbZs, status: FAILED)
149138
'408':
150139
description: ''
151140
headers: {}
@@ -168,23 +157,17 @@ get:
168157
summary: Without input
169158
description: |
170159
Runs a specific Actor and returns its output.
171-
172160
The run must finish in 300<!-- MAX_ACTOR_JOB_SYNC_WAIT_SECS --> seconds
173161
otherwise the API endpoint returns a timeout error.
174-
175162
The Actor is not passed any input.
176163
177-
178164
Beware that it might be impossible to maintain an idle HTTP connection for a
179165
long period of time,
180-
181166
due to client timeout or network conditions. Make sure your HTTP client is
182167
configured to have a long enough connection timeout.
183-
184168
If the connection breaks, you will not receive any information about the run
185169
and its status.
186170
187-
188171
To run the Actor asynchronously, use the [Run
189172
Actor](#/reference/actors/run-collection/run-actor) API endpoint instead.
190173
operationId: act_runSync_get
@@ -199,9 +182,9 @@ get:
199182
example: janedoe~my-actor
200183
- name: outputRecordKey
201184
in: query
202-
description: |-
185+
description: |
203186
Key of the record from run's default key-value store to be returned
204-
in the response. By default, it is `OUTPUT`.
187+
in the response. By default, it is `OUTPUT`.
205188
style: form
206189
explode: true
207190
schema:
@@ -260,12 +243,9 @@ get:
260243
description: |
261244
Specifies optional webhooks associated with the Actor run, which can be
262245
used to receive a notification
263-
264246
e.g. when the Actor finished or failed. The value is a Base64-encoded
265247
JSON array of objects defining the webhooks. For more information, see
266-
267-
[Webhooks
268-
documentation](https://docs.apify.com/platform/integrations/webhooks).
248+
[Webhooks documentation](https://docs.apify.com/platform/integrations/webhooks).
269249
style: form
270250
explode: true
271251
schema:

apify-docs-theme/src/theme/NotFound.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React from 'react';
21
import { PageMetadata } from '@docusaurus/theme-common';
32
import Layout from '@theme/Layout';
3+
import React from 'react';
44

55
export default function NotFound() {
66
return (

apify-docs-theme/src/theme/SearchPage/index.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
} from '@docusaurus/theme-common/internal';
1818
import Translate, { translate } from '@docusaurus/Translate';
1919
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
20+
import { useLocation } from '@docusaurus/router';
2021
import {
2122
useAlgoliaThemeConfig,
2223
useSearchResultUrlProcessor,
@@ -120,6 +121,8 @@ function SearchPageContent() {
120121
const documentsFoundPlural = useDocumentsFoundPlural();
121122
const docsSearchVersionsHelpers = useDocsSearchVersionsHelpers();
122123
const [searchQuery, setSearchQuery] = useSearchQueryString();
124+
const location = useLocation();
125+
const notFound = new URLSearchParams(location.search).get('not-found');
123126
const initialSearchResultState = {
124127
items: [],
125128
query: null,
@@ -302,7 +305,14 @@ function SearchPageContent() {
302305
</Head>
303306

304307
<div className="container margin-vert--lg">
305-
<h1>{getTitle()}</h1>
308+
{notFound ? (
309+
<>
310+
<h1>Page Not Found</h1>
311+
<h2>{getTitle()}</h2>
312+
</>
313+
) : (
314+
<h1>{getTitle()}</h1>
315+
)}
306316

307317
<form className="row" onSubmit={(e) => e.preventDefault()}>
308318
<div

apify-docs-theme/src/theme/custom.css

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,14 +990,19 @@ html[data-theme='dark'] .actionLink:hover::after {
990990
}
991991
}
992992

993-
aside li.section-header > div > .menu__link {
993+
aside li.section-header > div > .menu__link,
994+
aside li.section-header > ul > li > div > .menu__link {
994995
text-transform: uppercase;
995996
opacity: 0.8;
996997
font-size: 16px;
997998
font-weight: 700;
998999
margin: 0;
9991000
}
10001001

1002+
aside li.section-header > div > .menu__link {
1003+
font-size: 20px;
1004+
}
1005+
10011006
aside li.section-header.menu__list-item {
10021007
margin-top: 15px;
10031008
margin-bottom: 5px;
@@ -1011,6 +1016,11 @@ aside li.section-header > .menu__list {
10111016
padding-left: 0;
10121017
}
10131018

1019+
.theme-doc-sidebar-menu li.section-header > ul > li .menu__list-item-collapsible:hover,
1020+
.theme-doc-sidebar-menu li.section-header > ul > li .menu__list-item-collapsible--active {
1021+
background: inherit !important;
1022+
}
1023+
10141024
.beta-chip {
10151025
display: inline-block;
10161026
border: 1px solid #ccc;

apify-docs-theme/static/js/custom.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ function scrollSidebarItemIntoView() {
6363

6464
// handles automatic scrolling of the API reference sidebar (openapi-docs)
6565
function scrollOpenApiSidebarItemIntoView() {
66-
const $li = document.querySelector(`li > a.menu__link--active[href]`);
66+
const $li = document.querySelector(`ul.theme-doc-sidebar-menu a.menu__link--active[href]`);
6767

6868
if (!$li) {
6969
return;
@@ -76,27 +76,31 @@ function scrollOpenApiSidebarItemIntoView() {
7676
}
7777

7878
function redirectOpenApiDocs() {
79-
const { hash, pathname } = new URL(window.location.href);
79+
const { hash, pathname, origin } = new URL(window.location.href);
8080

8181
// TODO change to '/api/v2'
8282
if (pathname.replace(/\/$/, '') !== '/api/v2-new') {
8383
return;
8484
}
8585

86-
if (hash.startsWith('#/reference/')) {
87-
const sidebarItems = document.querySelectorAll('[data-altids]');
86+
const sidebarItems = document.querySelectorAll('[data-altids]');
87+
88+
if (hash.startsWith('#/reference/') || hash.startsWith('#tag/')) {
89+
let matched = false;
8890

8991
for (const item of sidebarItems) {
9092
const ids = item.getAttribute('data-altids').split(',');
93+
9194
if (ids.find((variant) => variant === hash)) {
95+
matched = true;
9296
item.click();
97+
setTimeout(() => scrollOpenApiSidebarItemIntoView(), 200);
9398
}
9499
}
95-
}
96100

97-
if (hash.startsWith('#tag/')) {
98-
const id = hash.substring('#tag/'.length);
99-
console.log('redirect', { id, hash });
101+
if (!matched) {
102+
window.location.href = `${origin}/search?q=${hash.slice(1)}&not-found=1`;
103+
}
100104
}
101105
}
102106

@@ -121,7 +125,7 @@ window.addEventListener('load', () => {
121125
setTimeout(() => scrollSidebarItemIntoView(), 1000);
122126

123127
// docusaurus-openapi-docs plugin: scroll sidebar into viewport, no need for a large timeout here
124-
setTimeout(() => scrollOpenApiSidebarItemIntoView(), 100);
128+
setTimeout(() => scrollOpenApiSidebarItemIntoView(), 200);
125129
});
126130

127131
window.addEventListener('popstate', () => {

docusaurus.config.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const { join } = require('node:path');
22

33
const clsx = require('clsx');
4+
const { createApiPageMD } = require('docusaurus-plugin-openapi-docs/lib/markdown');
45

56
const { config } = require('./apify-docs-theme');
67
const { collectSlugs } = require('./tools/utils/collectSlugs');
@@ -195,15 +196,28 @@ module.exports = {
195196
v2: {
196197
specPath: 'apify-api.yaml',
197198
outputDir: './sources/api',
199+
markdownGenerators: {
200+
createApiPageMD: (pageData) => {
201+
let md = createApiPageMD(pageData);
202+
203+
// HTML comments are wrongly escaped, we need to undo that
204+
if (md.includes('&lt;!--')) {
205+
md = md.replace('&lt;!--', '<!--');
206+
md = md.replace('--&gt;', '-->');
207+
}
208+
209+
return md;
210+
},
211+
},
198212
sidebarOptions: {
199-
groupPathsBy: 'tag',
213+
groupPathsBy: 'tagGroup',
200214
categoryLinkSource: 'tag',
201215
sidebarCollapsed: false,
202216
sidebarCollapsible: false,
203217
sidebarGenerators: {
204218
createDocItem: (item, context) => {
205219
const legacyUrls = item.api?.['x-legacy-doc-urls'] ?? [];
206-
const altIds = legacyUrls.map((url) => {
220+
const altids = legacyUrls.map((url) => {
207221
const { hash } = new URL(url);
208222
return hash;
209223
});
@@ -223,7 +237,7 @@ module.exports = {
223237
type: 'doc',
224238
id: context.basePath === '' ? `${id}` : `${context.basePath}/${id}`,
225239
label: sidebarLabel ?? title ?? id,
226-
customProps: { altIds },
240+
customProps: { altids },
227241
className,
228242
};
229243
},
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
diff --git a/node_modules/docusaurus-plugin-openapi-docs/lib/sidebars/index.js b/node_modules/docusaurus-plugin-openapi-docs/lib/sidebars/index.js
2+
index 5802904..576c3ed 100644
3+
--- a/node_modules/docusaurus-plugin-openapi-docs/lib/sidebars/index.js
4+
+++ b/node_modules/docusaurus-plugin-openapi-docs/lib/sidebars/index.js
5+
@@ -139,9 +139,16 @@ function groupByTags(items, sidebarOptions, options, tags, docPath) {
6+
}
7+
const taggedApiItems = apiItems.filter((item) => { var _a; return !!((_a = item.api.tags) === null || _a === void 0 ? void 0 : _a.includes(tag)); });
8+
const taggedSchemaItems = schemaItems.filter((item) => { var _a; return !!((_a = item.schema["x-tags"]) === null || _a === void 0 ? void 0 : _a.includes(tag)); });
9+
+ const altids = [];
10+
+
11+
+ if (tagObject?.['x-legacy-doc-urls']) {
12+
+ altids.push(...tagObject['x-legacy-doc-urls']);
13+
+ }
14+
+
15+
return {
16+
type: "category",
17+
label: (_a = tagObject === null || tagObject === void 0 ? void 0 : tagObject["x-displayName"]) !== null && _a !== void 0 ? _a : tag,
18+
+ customProps: { altids },
19+
link: linkConfig,
20+
collapsible: sidebarCollapsible,
21+
collapsed: sidebarCollapsed,
22+
@@ -201,11 +208,12 @@ function generateSidebarSlice(sidebarOptions, options, api, tags, docPath, tagGr
23+
filteredTags.push(tag);
24+
}
25+
});
26+
+ const { sidebarCollapsed, sidebarCollapsible } = sidebarOptions;
27+
const groupCategory = {
28+
type: "category",
29+
label: tagGroup.name,
30+
- collapsible: true,
31+
- collapsed: true,
32+
+ collapsible: sidebarCollapsible,
33+
+ collapsed: sidebarCollapsed,
34+
items: groupByTags(api, sidebarOptions, options, [filteredTags], docPath),
35+
};
36+
if (options.showSchemas) {

sources/api/sidebars.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1+
// eslint-disable-next-line global-require
2+
const items = require('./sidebar.ts');
3+
4+
for (const item of items) {
5+
// this is wrongly rendered in each category (openapi group tag)
6+
if (item.items[0].id === 'apify-api') {
7+
item.items.shift();
8+
}
9+
}
10+
111
module.exports = {
212
api: [
313
{
414
type: 'category',
515
label: 'Apify API',
616
collapsible: false,
717
className: 'section-header',
8-
// eslint-disable-next-line global-require
9-
items: require('./sidebar.ts'),
18+
link: { type: 'doc', id: 'apify-api' },
19+
items,
1020
},
1121
],
1222
};

0 commit comments

Comments
 (0)