mintlify 1.2.0 → 2.0.1
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/CONTRIBUTING.md +2 -0
- package/README.md +1 -1
- package/bin/index.js +0 -2
- package/bin/index.js.map +1 -1
- package/bin/local-preview/index.js +12 -60
- package/bin/local-preview/index.js.map +1 -1
- package/bin/local-preview/listener/categorizeFiles.js +47 -0
- package/bin/local-preview/listener/categorizeFiles.js.map +1 -0
- package/bin/local-preview/listener/generate.js +89 -0
- package/bin/local-preview/listener/generate.js.map +1 -0
- package/bin/local-preview/listener/index.js +135 -0
- package/bin/local-preview/listener/index.js.map +1 -0
- package/bin/local-preview/listener/update.js +41 -0
- package/bin/local-preview/listener/update.js.map +1 -0
- package/bin/local-preview/listener/utils/createPage.js +167 -0
- package/bin/local-preview/listener/utils/createPage.js.map +1 -0
- package/bin/local-preview/listener/utils/fileIsMdxOrMd.js +12 -0
- package/bin/local-preview/listener/utils/fileIsMdxOrMd.js.map +1 -0
- package/bin/local-preview/listener/utils/getOpenApiContext.js +57 -0
- package/bin/local-preview/listener/utils/getOpenApiContext.js.map +1 -0
- package/bin/local-preview/listener/utils/mintConfigFile.js +22 -0
- package/bin/local-preview/listener/utils/mintConfigFile.js.map +1 -0
- package/bin/local-preview/listener/utils/toTitleCase.js +36 -0
- package/bin/local-preview/listener/utils/toTitleCase.js.map +1 -0
- package/bin/local-preview/listener/utils/types.js +2 -0
- package/bin/local-preview/listener/utils/types.js.map +1 -0
- package/bin/local-preview/listener/utils.js +62 -0
- package/bin/local-preview/listener/utils.js.map +1 -0
- package/bin/scraping/detectFramework.js +1 -1
- package/bin/scraping/detectFramework.js.map +1 -1
- package/bin/scraping/scrapePageCommands.js +2 -2
- package/bin/scraping/scrapePageCommands.js.map +1 -1
- package/bin/scraping/site-scrapers/alternateGroupTitle.js +1 -1
- package/bin/scraping/site-scrapers/alternateGroupTitle.js.map +1 -1
- package/bin/scraping/site-scrapers/openNestedDocusaurusMenus.js +3 -3
- package/bin/scraping/site-scrapers/openNestedDocusaurusMenus.js.map +1 -1
- package/bin/scraping/site-scrapers/openNestedGitbookMenus.js +1 -2
- package/bin/scraping/site-scrapers/openNestedGitbookMenus.js.map +1 -1
- package/bin/util.js +40 -1
- package/bin/util.js.map +1 -1
- package/package.json +12 -5
- package/src/index.ts +0 -2
- package/src/local-preview/index.ts +14 -74
- package/src/local-preview/listener/categorizeFiles.ts +55 -0
- package/src/local-preview/listener/generate.ts +110 -0
- package/src/local-preview/listener/index.ts +169 -0
- package/src/local-preview/listener/update.ts +45 -0
- package/src/local-preview/listener/utils/createPage.ts +211 -0
- package/src/local-preview/listener/utils/fileIsMdxOrMd.ts +11 -0
- package/src/local-preview/{utils → listener/utils}/getOpenApiContext.ts +0 -0
- package/src/local-preview/listener/utils/mintConfigFile.ts +28 -0
- package/src/local-preview/listener/utils/toTitleCase.ts +40 -0
- package/src/local-preview/listener/utils/types.ts +1 -0
- package/src/local-preview/listener/utils.ts +69 -0
- package/src/scraping/scrapePageCommands.ts +2 -2
- package/src/util.ts +54 -1
- package/tsconfig.json +6 -5
- package/bin/local-preview/categorizeFiles.js +0 -56
- package/bin/local-preview/categorizeFiles.js.map +0 -1
- package/bin/local-preview/getOpenApiContext.js +0 -46
- package/bin/local-preview/getOpenApiContext.js.map +0 -1
- package/bin/local-preview/helper-commands/clearCommand.js +0 -27
- package/bin/local-preview/helper-commands/clearCommand.js.map +0 -1
- package/bin/local-preview/injectFavicons.js +0 -72
- package/bin/local-preview/injectFavicons.js.map +0 -1
- package/bin/local-preview/injectNav.js +0 -94
- package/bin/local-preview/injectNav.js.map +0 -1
- package/bin/local-preview/listener.js +0 -112
- package/bin/local-preview/listener.js.map +0 -1
- package/bin/local-preview/metadata.js +0 -121
- package/bin/local-preview/metadata.js.map +0 -1
- package/bin/local-preview/mintConfigFile.js +0 -43
- package/bin/local-preview/mintConfigFile.js.map +0 -1
- package/bin/local-preview/openApiCheck.js +0 -16
- package/bin/local-preview/openApiCheck.js.map +0 -1
- package/bin/local-preview/slugToTitle.js +0 -8
- package/bin/local-preview/slugToTitle.js.map +0 -1
- package/bin/mint/client/.babel-plugin-macrosrc.json +0 -5
- package/bin/mint/client/.babelrc +0 -4
- package/bin/mint/client/.editorconfig +0 -12
- package/bin/mint/client/.eslintrc.json +0 -7
- package/bin/mint/client/.prettierignore +0 -4
- package/bin/mint/client/.prettierrc +0 -14
- package/bin/mint/client/.vscode/launch.json +0 -28
- package/bin/mint/client/README.md +0 -44
- package/bin/mint/client/jest.config.ts +0 -195
- package/bin/mint/client/next-env.d.ts +0 -4
- package/bin/mint/client/next.config.js +0 -152
- package/bin/mint/client/package.json +0 -139
- package/bin/mint/client/postcss.config.cjs +0 -9
- package/bin/mint/client/prebuild/faviconConfig.js +0 -35
- package/bin/mint/client/prebuild/getOpenApiContext.js +0 -53
- package/bin/mint/client/prebuild/index.js +0 -117
- package/bin/mint/client/prebuild/injectNav.js +0 -115
- package/bin/mint/client/prebuild/slugToTitle.js +0 -7
- package/bin/mint/client/rehype/withApiComponents.js +0 -60
- package/bin/mint/client/rehype/withCodeBlocks.js +0 -54
- package/bin/mint/client/rehype/withLayouts.js +0 -113
- package/bin/mint/client/rehype/withLinkRoles.js +0 -13
- package/bin/mint/client/rehype/withRawComponents.js +0 -13
- package/bin/mint/client/rehype/withStaticProps.js +0 -25
- package/bin/mint/client/rehype/withSyntaxHighlighting.js +0 -60
- package/bin/mint/client/remark/utils.js +0 -369
- package/bin/mint/client/remark/withFrames.js +0 -55
- package/bin/mint/client/remark/withImportsInjected.js +0 -36
- package/bin/mint/client/remark/withNextLinks.js +0 -37
- package/bin/mint/client/remark/withTableOfContents.js +0 -71
- package/bin/mint/client/scripts/local.js +0 -177
- package/bin/mint/client/sentry.client.config.js +0 -15
- package/bin/mint/client/sentry.properties +0 -4
- package/bin/mint/client/sentry.server.config.js +0 -15
- package/bin/mint/client/src/analytics/AbstractAnalyticsImplementation.ts +0 -50
- package/bin/mint/client/src/analytics/AnalyticsContext.ts +0 -5
- package/bin/mint/client/src/analytics/AnalyticsMediator.ts +0 -101
- package/bin/mint/client/src/analytics/FakeAnalyticsMediator.ts +0 -9
- package/bin/mint/client/src/analytics/GA4Script.tsx +0 -33
- package/bin/mint/client/src/analytics/implementations/amplitude.ts +0 -26
- package/bin/mint/client/src/analytics/implementations/fathom.ts +0 -38
- package/bin/mint/client/src/analytics/implementations/ga4.ts +0 -33
- package/bin/mint/client/src/analytics/implementations/hotjar.ts +0 -53
- package/bin/mint/client/src/analytics/implementations/mixpanel-browser.d.ts +0 -1
- package/bin/mint/client/src/analytics/implementations/mixpanel.ts +0 -52
- package/bin/mint/client/src/analytics/implementations/posthog.ts +0 -37
- package/bin/mint/client/src/components/Accordion/Accordion.tsx +0 -43
- package/bin/mint/client/src/components/Accordion/index.ts +0 -4
- package/bin/mint/client/src/components/ApiExample.tsx +0 -9
- package/bin/mint/client/src/components/Card.tsx +0 -51
- package/bin/mint/client/src/components/CodeGroup.tsx +0 -132
- package/bin/mint/client/src/components/Editor.tsx +0 -12
- package/bin/mint/client/src/components/Expandable.tsx +0 -40
- package/bin/mint/client/src/components/Heading.tsx +0 -84
- package/bin/mint/client/src/components/Param.tsx +0 -56
- package/bin/mint/client/src/components/Request.tsx +0 -19
- package/bin/mint/client/src/components/ResponseField.tsx +0 -33
- package/bin/mint/client/src/components/TabBar.tsx +0 -61
- package/bin/mint/client/src/config.ts +0 -115
- package/bin/mint/client/src/css/bar-of-progress.css +0 -10
- package/bin/mint/client/src/css/base.css +0 -29
- package/bin/mint/client/src/css/font-awesome.css +0 -7
- package/bin/mint/client/src/css/fonts.css +0 -44
- package/bin/mint/client/src/css/main.css +0 -11
- package/bin/mint/client/src/css/prism.css +0 -270
- package/bin/mint/client/src/css/utilities.css +0 -43
- package/bin/mint/client/src/enums/components.ts +0 -8
- package/bin/mint/client/src/fonts/FiraCode-VF.woff +0 -0
- package/bin/mint/client/src/fonts/FiraCode-VF.woff2 +0 -0
- package/bin/mint/client/src/fonts/IBMPlexMono-Regular.ttf +0 -0
- package/bin/mint/client/src/fonts/IBMPlexMono-SemiBold.ttf +0 -0
- package/bin/mint/client/src/fonts/Inter-italic-latin.var.woff2 +0 -0
- package/bin/mint/client/src/fonts/Inter-roman-latin.var.woff2 +0 -0
- package/bin/mint/client/src/fonts/Pally-Variable.ttf +0 -0
- package/bin/mint/client/src/fonts/SourceSansPro-Regular.otf +0 -0
- package/bin/mint/client/src/fonts/SourceSerifPro-Regular.ttf +0 -0
- package/bin/mint/client/src/fonts/Synonym-Variable.ttf +0 -0
- package/bin/mint/client/src/fonts/Ubuntu-Mono-bold.woff2 +0 -0
- package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular-subset.woff2 +0 -0
- package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular-subset.zopfli.woff +0 -0
- package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular.module.css +0 -11
- package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold-subset.woff2 +0 -0
- package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold-subset.zopfli.woff +0 -0
- package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold.module.css +0 -11
- package/bin/mint/client/src/fonts/generated/Pally-Variable-subset.woff2 +0 -0
- package/bin/mint/client/src/fonts/generated/Pally-Variable-subset.zopfli.woff +0 -0
- package/bin/mint/client/src/fonts/generated/Pally-Variable.module.css +0 -11
- package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular-subset.woff2 +0 -0
- package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular-subset.zopfli.woff +0 -0
- package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular.module.css +0 -11
- package/bin/mint/client/src/fonts/generated/Synonym-Variable-subset.woff2 +0 -0
- package/bin/mint/client/src/fonts/generated/Synonym-Variable-subset.zopfli.woff +0 -0
- package/bin/mint/client/src/fonts/generated/Synonym-Variable.module.css +0 -11
- package/bin/mint/client/src/fonts/generated/TenorSans-Regular-subset.woff2 +0 -0
- package/bin/mint/client/src/fonts/generated/TenorSans-Regular-subset.zopfli.woff +0 -0
- package/bin/mint/client/src/fonts/generated/TenorSans-Regular.module.css +0 -11
- package/bin/mint/client/src/hooks/useActionKey.ts +0 -20
- package/bin/mint/client/src/hooks/useIsomorphicLayoutEffect.ts +0 -3
- package/bin/mint/client/src/hooks/useMedia.ts +0 -27
- package/bin/mint/client/src/hooks/usePrevNext.ts +0 -34
- package/bin/mint/client/src/hooks/useTop.ts +0 -15
- package/bin/mint/client/src/icons/CopyToClipboard.tsx +0 -33
- package/bin/mint/client/src/index.d.ts +0 -1
- package/bin/mint/client/src/layouts/ApiSupplemental.tsx +0 -173
- package/bin/mint/client/src/layouts/ContentsLayout.tsx +0 -256
- package/bin/mint/client/src/layouts/DocumentationLayout.tsx +0 -44
- package/bin/mint/client/src/layouts/OpenApiContent.tsx +0 -301
- package/bin/mint/client/src/layouts/SidebarLayout.tsx +0 -412
- package/bin/mint/client/src/layouts/UserFeedback.tsx +0 -73
- package/bin/mint/client/src/layouts/getGroupsInDivision.ts +0 -25
- package/bin/mint/client/src/layouts/isPathInGroupPages.ts +0 -10
- package/bin/mint/client/src/metadata.ts +0 -58
- package/bin/mint/client/src/nav.json +0 -219
- package/bin/mint/client/src/openapi.ts +0 -3
- package/bin/mint/client/src/pages/404.tsx +0 -73
- package/bin/mint/client/src/pages/_app.tsx +0 -138
- package/bin/mint/client/src/pages/_document.tsx +0 -57
- package/bin/mint/client/src/pages/api/issue.ts +0 -10
- package/bin/mint/client/src/pages/api/name.ts +0 -8
- package/bin/mint/client/src/pages/api/request.ts +0 -31
- package/bin/mint/client/src/pages/api/suggest.ts +0 -10
- package/bin/mint/client/src/pages/api/syntax-highlighted-json.ts +0 -13
- package/bin/mint/client/src/pages/api/utils.ts +0 -6
- package/bin/mint/client/src/pages/index.tsx +0 -31
- package/bin/mint/client/src/ui/Api.tsx +0 -359
- package/bin/mint/client/src/ui/Footer.tsx +0 -124
- package/bin/mint/client/src/ui/Header.tsx +0 -370
- package/bin/mint/client/src/ui/Logo.tsx +0 -55
- package/bin/mint/client/src/ui/PageHeader.tsx +0 -51
- package/bin/mint/client/src/ui/Search.tsx +0 -386
- package/bin/mint/client/src/ui/ThemeToggle.tsx +0 -285
- package/bin/mint/client/src/ui/Title.tsx +0 -22
- package/bin/mint/client/src/ui/TopLevelLink.tsx +0 -122
- package/bin/mint/client/src/utils/api.ts +0 -252
- package/bin/mint/client/src/utils/brands.ts +0 -217
- package/bin/mint/client/src/utils/castArray.ts +0 -3
- package/bin/mint/client/src/utils/childrenArray.ts +0 -3
- package/bin/mint/client/src/utils/fit.ts +0 -27
- package/bin/mint/client/src/utils/fontAwesome.ts +0 -577
- package/bin/mint/client/src/utils/getAnalyticsConfig.ts +0 -14
- package/bin/mint/client/src/utils/getLogoHref.ts +0 -9
- package/bin/mint/client/src/utils/getOpenApiContext.ts +0 -26
- package/bin/mint/client/src/utils/importAll.ts +0 -6
- package/bin/mint/client/src/utils/isObject.ts +0 -3
- package/bin/mint/client/src/utils/kebabToTitleCase.ts +0 -3
- package/bin/mint/client/src/utils/loadImage.ts +0 -8
- package/bin/mint/client/src/utils/slugToTitle.ts +0 -7
- package/bin/mint/client/src/utils/wait.ts +0 -5
- package/bin/mint/client/tailwind.config.cjs +0 -323
- package/bin/mint/client/test/test.test.ts +0 -5
- package/bin/mint/client/tsconfig.json +0 -36
- package/bin/mint/client/yarn.lock +0 -9702
- package/bin/scraping/site-scrapers/getLinksRecursively.js +0 -38
- package/bin/scraping/site-scrapers/getLinksRecursively.js.map +0 -1
- package/src/init-command/index.ts +0 -59
- package/src/init-command/templates.ts +0 -52
- package/src/local-preview/utils/categorizeFiles.ts +0 -82
- package/src/local-preview/utils/injectFavicons.ts +0 -76
- package/src/local-preview/utils/listener.ts +0 -124
- package/src/local-preview/utils/metadata.ts +0 -151
- package/src/local-preview/utils/mintConfigFile.ts +0 -48
- package/src/local-preview/utils/openApiCheck.ts +0 -18
- package/src/local-preview/utils/slugToTitle.ts +0 -7
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { withSentry } from '@sentry/nextjs';
|
|
2
|
-
import axios from 'axios';
|
|
3
|
-
import { NextApiRequest, NextApiResponse } from 'next';
|
|
4
|
-
|
|
5
|
-
import { jsonSyntaxHighlight } from './utils';
|
|
6
|
-
|
|
7
|
-
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
8
|
-
const { url, method, body, params, headers } = req.body;
|
|
9
|
-
try {
|
|
10
|
-
const response = await axios({
|
|
11
|
-
url,
|
|
12
|
-
method,
|
|
13
|
-
params,
|
|
14
|
-
data: body,
|
|
15
|
-
headers,
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
res.send({
|
|
19
|
-
response: response.data,
|
|
20
|
-
highlightedJson: jsonSyntaxHighlight(response.data),
|
|
21
|
-
});
|
|
22
|
-
} catch (error: any) {
|
|
23
|
-
const response = error.response;
|
|
24
|
-
res.send({
|
|
25
|
-
response: response?.data,
|
|
26
|
-
highlightedJson: jsonSyntaxHighlight(response?.data),
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default withSentry(handler);
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
|
|
3
|
-
function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
4
|
-
const { path } = req.query;
|
|
5
|
-
return res.redirect(
|
|
6
|
-
`https://docs.mintlify.com/api/v1/app/suggest/${process.env.NAME}?path=${path}.mdx`
|
|
7
|
-
);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default handler;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { withSentry } from '@sentry/nextjs';
|
|
2
|
-
import { NextApiRequest, NextApiResponse } from 'next';
|
|
3
|
-
import { jsonSyntaxHighlight } from './utils';
|
|
4
|
-
|
|
5
|
-
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
6
|
-
const { json } = req.body;
|
|
7
|
-
const highlightedJson = jsonSyntaxHighlight(json);
|
|
8
|
-
return res.send({
|
|
9
|
-
highlightedJson,
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default withSentry(handler);
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { config, Navigation } from '@/config';
|
|
2
|
-
import { DocumentationLayout } from '@/layouts/DocumentationLayout';
|
|
3
|
-
|
|
4
|
-
const getFirstPage = (nav: Navigation | string): string | void => {
|
|
5
|
-
if (typeof nav === 'string') {
|
|
6
|
-
return nav;
|
|
7
|
-
} else if (typeof nav !== 'string' && nav.group && nav.pages) {
|
|
8
|
-
return getFirstPage(nav.pages[0]);
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export default function Index() {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export async function getServerSideProps() {
|
|
17
|
-
return {
|
|
18
|
-
redirect: {
|
|
19
|
-
destination: `/${(config?.navigation && getFirstPage(config.navigation[0])) || ''}`,
|
|
20
|
-
permanent: false,
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
Index.layoutProps = {
|
|
26
|
-
meta: {
|
|
27
|
-
title: 'Introduction',
|
|
28
|
-
},
|
|
29
|
-
Layout: DocumentationLayout,
|
|
30
|
-
allowOverflow: false,
|
|
31
|
-
};
|
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import clsx from 'clsx';
|
|
3
|
-
import { useEffect, useState } from 'react';
|
|
4
|
-
|
|
5
|
-
import { config } from '@/config';
|
|
6
|
-
import {
|
|
7
|
-
extractBaseAndPath,
|
|
8
|
-
extractMethodAndEndpoint,
|
|
9
|
-
getApiContext,
|
|
10
|
-
getParamGroupsFromAPIComponents,
|
|
11
|
-
MediaType,
|
|
12
|
-
Param,
|
|
13
|
-
ParamGroup,
|
|
14
|
-
} from '@/utils/api';
|
|
15
|
-
import {
|
|
16
|
-
getMethodBgColor,
|
|
17
|
-
getMethodBgColorWithHover,
|
|
18
|
-
getMethodBorderColor,
|
|
19
|
-
getMethodTextColor,
|
|
20
|
-
} from '@/utils/brands';
|
|
21
|
-
|
|
22
|
-
export type ApiComponent = {
|
|
23
|
-
type: string;
|
|
24
|
-
children?: any;
|
|
25
|
-
attributes?: {
|
|
26
|
-
type: string;
|
|
27
|
-
name: string;
|
|
28
|
-
value: string;
|
|
29
|
-
}[];
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const APIBASE_CONFIG_STORAGE = 'apiBaseIndex';
|
|
33
|
-
|
|
34
|
-
export function Api({
|
|
35
|
-
api,
|
|
36
|
-
media = 'json',
|
|
37
|
-
auth,
|
|
38
|
-
children,
|
|
39
|
-
apiComponents,
|
|
40
|
-
}: {
|
|
41
|
-
api: string;
|
|
42
|
-
media?: MediaType;
|
|
43
|
-
auth?: string;
|
|
44
|
-
children?: any;
|
|
45
|
-
apiComponents?: ApiComponent[];
|
|
46
|
-
}) {
|
|
47
|
-
const [apiBaseIndex, setApiBaseIndex] = useState(0);
|
|
48
|
-
const { method, endpoint } = extractMethodAndEndpoint(api);
|
|
49
|
-
const { base, path } = extractBaseAndPath(endpoint, apiBaseIndex);
|
|
50
|
-
|
|
51
|
-
const paramGroups = getParamGroupsFromAPIComponents(apiComponents, auth);
|
|
52
|
-
const [currentActiveParamGroup, setCurrentActiveParamGroup] = useState<ParamGroup>(
|
|
53
|
-
paramGroups[0]
|
|
54
|
-
);
|
|
55
|
-
const [isSendingRequest, setIsSendingResponse] = useState<boolean>(false);
|
|
56
|
-
const [apiBase, setApiBase] = useState<string>(base);
|
|
57
|
-
const [hasConfiguredApiBase, setHasConfiguredApiBase] = useState(false);
|
|
58
|
-
const [inputData, setInputData] = useState<Record<string, any>>({});
|
|
59
|
-
const [apiResponse, setApiResponse] = useState<string>();
|
|
60
|
-
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
setHasConfiguredApiBase(window.localStorage.getItem(APIBASE_CONFIG_STORAGE) != null);
|
|
63
|
-
|
|
64
|
-
const configuredApiBaseIndex = window.localStorage.getItem(APIBASE_CONFIG_STORAGE);
|
|
65
|
-
if (configuredApiBaseIndex != null) {
|
|
66
|
-
setApiBaseIndex(parseInt(configuredApiBaseIndex, 10));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Configure api auth prefix
|
|
70
|
-
// TODO: Standardize to work without auth name and reliable for different methods
|
|
71
|
-
if (config.api?.auth?.inputPrefix && config.api.auth.name) {
|
|
72
|
-
setInputData({
|
|
73
|
-
...inputData,
|
|
74
|
-
Authorization: {
|
|
75
|
-
...inputData.Authorization,
|
|
76
|
-
[config.api.auth.name]: config.api.auth.inputPrefix,
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}, [api, children]);
|
|
81
|
-
|
|
82
|
-
const onChangeApiBaseSelection = (base: string) => {
|
|
83
|
-
if (config.api == null || !Array.isArray(config.api?.baseUrl)) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const index = config.api.baseUrl.indexOf(base);
|
|
87
|
-
window.localStorage.setItem(APIBASE_CONFIG_STORAGE, index.toString());
|
|
88
|
-
setApiBase(base);
|
|
89
|
-
setHasConfiguredApiBase(true);
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const onChangeParam = (
|
|
93
|
-
paramGroup: string,
|
|
94
|
-
param: string,
|
|
95
|
-
value: string | number | boolean | File
|
|
96
|
-
) => {
|
|
97
|
-
setInputData({ ...inputData, [paramGroup]: { ...inputData[paramGroup], [param]: value } });
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const makeApiRequest = async () => {
|
|
101
|
-
setIsSendingResponse(true);
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
const apiContext = getApiContext(apiBase, path, inputData, media);
|
|
105
|
-
const { data } = await axios.post('/api/request', {
|
|
106
|
-
method,
|
|
107
|
-
...apiContext,
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
setApiResponse(data.highlightedJson);
|
|
111
|
-
} catch (error: any) {
|
|
112
|
-
setApiResponse(error.highlightedJson);
|
|
113
|
-
} finally {
|
|
114
|
-
setIsSendingResponse(false);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const renderInput = (
|
|
119
|
-
paramGroup: ParamGroup,
|
|
120
|
-
param: Param,
|
|
121
|
-
type?: string,
|
|
122
|
-
enumValues?: string[]
|
|
123
|
-
) => {
|
|
124
|
-
switch (type?.toLowerCase()) {
|
|
125
|
-
case 'boolean':
|
|
126
|
-
return (
|
|
127
|
-
<div className="relative">
|
|
128
|
-
<select
|
|
129
|
-
className="w-full py-0.5 px-2 rounded border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-800 cursor-pointer"
|
|
130
|
-
onChange={(e) => {
|
|
131
|
-
const selection = e.target.value;
|
|
132
|
-
if (selection === 'true') {
|
|
133
|
-
onChangeParam(paramGroup.name, param.name, true);
|
|
134
|
-
} else {
|
|
135
|
-
onChangeParam(paramGroup.name, param.name, false);
|
|
136
|
-
}
|
|
137
|
-
}}
|
|
138
|
-
>
|
|
139
|
-
<option disabled selected>
|
|
140
|
-
Select
|
|
141
|
-
</option>
|
|
142
|
-
<option>true</option>
|
|
143
|
-
<option>false</option>
|
|
144
|
-
</select>
|
|
145
|
-
<svg
|
|
146
|
-
className="absolute right-2 top-[7px] h-3 fill-slate-600 dark:fill-slate-400"
|
|
147
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
148
|
-
viewBox="0 0 384 512"
|
|
149
|
-
>
|
|
150
|
-
<path d="M192 384c-8.188 0-16.38-3.125-22.62-9.375l-160-160c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L192 306.8l137.4-137.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-160 160C208.4 380.9 200.2 384 192 384z" />
|
|
151
|
-
</svg>
|
|
152
|
-
</div>
|
|
153
|
-
);
|
|
154
|
-
case 'integer':
|
|
155
|
-
case 'number':
|
|
156
|
-
return (
|
|
157
|
-
<input
|
|
158
|
-
className="w-full py-0.5 px-2 rounded border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-700 text-slate-700 dark:text-slate-200"
|
|
159
|
-
type="number"
|
|
160
|
-
placeholder={param.placeholder}
|
|
161
|
-
value={inputData[paramGroup.name] ? inputData[paramGroup.name][param.name] : ''}
|
|
162
|
-
onChange={(e) =>
|
|
163
|
-
onChangeParam(paramGroup.name, param.name, parseInt(e.target.value, 10))
|
|
164
|
-
}
|
|
165
|
-
/>
|
|
166
|
-
);
|
|
167
|
-
case 'file':
|
|
168
|
-
return (
|
|
169
|
-
<button className="relative flex items-center px-2 w-full h-7 rounded border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-700 dark:text-slate-200 border-dashed hover:bg-slate-50 dark:hover:bg-slate-800">
|
|
170
|
-
<input
|
|
171
|
-
className="z-10 absolute inset-0 opacity-0 cursor-pointer"
|
|
172
|
-
type="file"
|
|
173
|
-
onChange={(event) => {
|
|
174
|
-
if (event.target.files == null) {
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
onChangeParam(paramGroup.name, param.name, event.target.files[0]);
|
|
179
|
-
}}
|
|
180
|
-
/>
|
|
181
|
-
<svg
|
|
182
|
-
className="absolute right-2 top-[7px] h-3 fill-slate-500 dark:fill-slate-400 bg-border-slate-700"
|
|
183
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
184
|
-
viewBox="0 0 512 512"
|
|
185
|
-
>
|
|
186
|
-
<path d="M105.4 182.6c12.5 12.49 32.76 12.5 45.25 .001L224 109.3V352c0 17.67 14.33 32 32 32c17.67 0 32-14.33 32-32V109.3l73.38 73.38c12.49 12.49 32.75 12.49 45.25-.001c12.49-12.49 12.49-32.75 0-45.25l-128-128C272.4 3.125 264.2 0 256 0S239.6 3.125 233.4 9.375L105.4 137.4C92.88 149.9 92.88 170.1 105.4 182.6zM480 352h-160c0 35.35-28.65 64-64 64s-64-28.65-64-64H32c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h448c17.67 0 32-14.33 32-32v-96C512 366.3 497.7 352 480 352zM432 456c-13.2 0-24-10.8-24-24c0-13.2 10.8-24 24-24s24 10.8 24 24C456 445.2 445.2 456 432 456z" />
|
|
187
|
-
</svg>
|
|
188
|
-
{inputData[paramGroup.name] != null &&
|
|
189
|
-
inputData[paramGroup.name][param.name] != null ? (
|
|
190
|
-
<span className="w-full truncate">{inputData[paramGroup.name][param.name].name}</span>
|
|
191
|
-
) : (
|
|
192
|
-
'Choose file'
|
|
193
|
-
)}
|
|
194
|
-
</button>
|
|
195
|
-
);
|
|
196
|
-
default:
|
|
197
|
-
if (enumValues) {
|
|
198
|
-
return (
|
|
199
|
-
<div className="relative">
|
|
200
|
-
<select
|
|
201
|
-
className="w-full py-0.5 px-2 rounded border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-700 dark:text-slate-200 hover:bg-slate-50 dark:hover:bg-slate-800 cursor-pointer"
|
|
202
|
-
onChange={(e) => {
|
|
203
|
-
const selection = e.target.value;
|
|
204
|
-
onChangeParam(paramGroup.name, param.name, selection);
|
|
205
|
-
}}
|
|
206
|
-
>
|
|
207
|
-
<option disabled selected>
|
|
208
|
-
Select
|
|
209
|
-
</option>
|
|
210
|
-
{enumValues.map((enumValue) => (
|
|
211
|
-
<option>{enumValue}</option>
|
|
212
|
-
))}
|
|
213
|
-
</select>
|
|
214
|
-
<svg
|
|
215
|
-
className="absolute right-2 top-[7px] h-3 fill-slate-600 dark:fill-slate-400"
|
|
216
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
217
|
-
viewBox="0 0 384 512"
|
|
218
|
-
>
|
|
219
|
-
<path d="M192 384c-8.188 0-16.38-3.125-22.62-9.375l-160-160c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L192 306.8l137.4-137.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-160 160C208.4 380.9 200.2 384 192 384z" />
|
|
220
|
-
</svg>
|
|
221
|
-
</div>
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
return (
|
|
225
|
-
<input
|
|
226
|
-
className="w-full py-0.5 px-2 rounded border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-700 text-slate-700 dark:text-slate-200"
|
|
227
|
-
type="text"
|
|
228
|
-
placeholder={param.placeholder}
|
|
229
|
-
value={inputData[paramGroup.name] ? inputData[paramGroup.name][param.name] : ''}
|
|
230
|
-
onChange={(e) => onChangeParam(paramGroup.name, param.name, e.target.value)}
|
|
231
|
-
/>
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
return (
|
|
237
|
-
<div className="mt-4 border border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-800 rounded-md truncate">
|
|
238
|
-
<div className="px-3 pt-3 pb-4">
|
|
239
|
-
<div className="text-sm md:text-base flex items-center space-x-2">
|
|
240
|
-
{method && (
|
|
241
|
-
<div
|
|
242
|
-
className={clsx(
|
|
243
|
-
'text-white font-bold px-1.5 rounded-md text-[0.95rem]',
|
|
244
|
-
getMethodBgColor(method)
|
|
245
|
-
)}
|
|
246
|
-
>
|
|
247
|
-
{method}
|
|
248
|
-
</div>
|
|
249
|
-
)}
|
|
250
|
-
{/* Only display dropdown when there are multiple endpoints */}
|
|
251
|
-
{config.api?.baseUrl && Array.isArray(config.api?.baseUrl) && (
|
|
252
|
-
<div
|
|
253
|
-
className={clsx(
|
|
254
|
-
'relative select-none align-middle inline-flex rounded-md -top-px mx-1 w-5 h-[1.125rem] bg-white hover:bg-slate-100 dark:bg-slate-700 dark:hover:bg-slate-600 border hover:border-slate-400 dark:hover:border-slate-400 focus:outline-none cursor-pointer',
|
|
255
|
-
hasConfiguredApiBase
|
|
256
|
-
? 'border-slate-400 dark:border-slate-400'
|
|
257
|
-
: 'border-slate-300 dark:border-slate-600'
|
|
258
|
-
)}
|
|
259
|
-
>
|
|
260
|
-
<select
|
|
261
|
-
aria-label="Expand api endpoint"
|
|
262
|
-
aria-expanded="false"
|
|
263
|
-
className="z-10 absolute inset-0 opacity-0 cursor-pointer"
|
|
264
|
-
onChange={(e) => onChangeApiBaseSelection(e.target.value)}
|
|
265
|
-
>
|
|
266
|
-
<option disabled>Select API base</option>
|
|
267
|
-
{config.api.baseUrl.map((base) => (
|
|
268
|
-
<option key={base} selected={base === apiBase}>
|
|
269
|
-
{base}
|
|
270
|
-
</option>
|
|
271
|
-
))}
|
|
272
|
-
</select>
|
|
273
|
-
<svg
|
|
274
|
-
width="20"
|
|
275
|
-
height="20"
|
|
276
|
-
fill="none"
|
|
277
|
-
className="transform absolute -top-0.5 -left-px rotate-90"
|
|
278
|
-
>
|
|
279
|
-
<path
|
|
280
|
-
className="stroke-slate-700 dark:stroke-slate-100"
|
|
281
|
-
d="M9 7l3 3-3 3"
|
|
282
|
-
strokeWidth="1.5"
|
|
283
|
-
strokeLinecap="round"
|
|
284
|
-
strokeLinejoin="round"
|
|
285
|
-
></path>
|
|
286
|
-
</svg>
|
|
287
|
-
</div>
|
|
288
|
-
)}
|
|
289
|
-
<div className="font-mono text-[0.95rem] overflow-auto">
|
|
290
|
-
<span className="text-slate-700 dark:text-slate-100 font-semibold">{path}</span>
|
|
291
|
-
</div>
|
|
292
|
-
</div>
|
|
293
|
-
<div className="text-sm">
|
|
294
|
-
<div className="mt-2 block">
|
|
295
|
-
<div className="border-b border-slate-200 dark:border-slate-600">
|
|
296
|
-
<nav className="-mb-px flex space-x-4" aria-label="Tabs">
|
|
297
|
-
{paramGroups.map((paramGroup: ParamGroup) => (
|
|
298
|
-
<button
|
|
299
|
-
key={paramGroup.name}
|
|
300
|
-
className={clsx(
|
|
301
|
-
currentActiveParamGroup?.name === paramGroup.name
|
|
302
|
-
? `${getMethodTextColor(method)} ${getMethodBorderColor(method)}`
|
|
303
|
-
: 'border-transparent text-slate-500 hover:text-slate-700 hover:border-slate-300 dark:text-slate-400 dark:hover:text-slate-200',
|
|
304
|
-
'whitespace-nowrap py-2 border-b-2 font-medium text-[0.84rem]'
|
|
305
|
-
)}
|
|
306
|
-
onClick={() => setCurrentActiveParamGroup(paramGroup)}
|
|
307
|
-
>
|
|
308
|
-
{paramGroup.name}
|
|
309
|
-
</button>
|
|
310
|
-
))}
|
|
311
|
-
</nav>
|
|
312
|
-
</div>
|
|
313
|
-
</div>
|
|
314
|
-
<div className="mt-4 text-[0.84rem] space-y-2">
|
|
315
|
-
{currentActiveParamGroup?.params.map((param) => (
|
|
316
|
-
<div className="flex items-center space-x-2">
|
|
317
|
-
<div className="flex-1 font-mono text-slate-600 dark:text-slate-300">
|
|
318
|
-
{param.name}
|
|
319
|
-
{param.required && <span className="text-red-600 dark:text-red-400">*</span>}
|
|
320
|
-
</div>
|
|
321
|
-
<div className="flex-initial w-1/3">
|
|
322
|
-
{renderInput(currentActiveParamGroup, param, param.type, param.enum)}
|
|
323
|
-
</div>
|
|
324
|
-
</div>
|
|
325
|
-
))}
|
|
326
|
-
</div>
|
|
327
|
-
<button
|
|
328
|
-
className={clsx(
|
|
329
|
-
'flex items-center py-1.5 px-3 rounded text-white font-medium space-x-2',
|
|
330
|
-
getMethodBgColorWithHover(method),
|
|
331
|
-
currentActiveParamGroup && 'mt-4'
|
|
332
|
-
)}
|
|
333
|
-
disabled={isSendingRequest}
|
|
334
|
-
onClick={makeApiRequest}
|
|
335
|
-
>
|
|
336
|
-
<svg
|
|
337
|
-
className="fill-white h-3"
|
|
338
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
339
|
-
viewBox="0 0 384 512"
|
|
340
|
-
>
|
|
341
|
-
<path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" />
|
|
342
|
-
</svg>
|
|
343
|
-
<div>{!isSendingRequest ? 'Send Request' : 'Sending...'}</div>
|
|
344
|
-
</button>
|
|
345
|
-
</div>
|
|
346
|
-
</div>
|
|
347
|
-
{!isSendingRequest && apiResponse && (
|
|
348
|
-
<div className="py-3 px-3 max-h-48 whitespace-pre overflow-scroll border-t border-slate-200 dark:border-slate-700 dark:text-slate-300 font-mono text-xs leading-5">
|
|
349
|
-
<span
|
|
350
|
-
className="language-json max-h-72 overflow-scroll"
|
|
351
|
-
dangerouslySetInnerHTML={{
|
|
352
|
-
__html: apiResponse,
|
|
353
|
-
}}
|
|
354
|
-
/>
|
|
355
|
-
</div>
|
|
356
|
-
)}
|
|
357
|
-
</div>
|
|
358
|
-
);
|
|
359
|
-
}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import Link from 'next/link';
|
|
2
|
-
import clsx from 'clsx';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { config } from '../config';
|
|
5
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
6
|
-
import { isBrandFontAwesomeIcon } from '@/utils/fontAwesome';
|
|
7
|
-
|
|
8
|
-
type FooterProps = {
|
|
9
|
-
children?: React.ReactChild;
|
|
10
|
-
previous?: any;
|
|
11
|
-
next?: any;
|
|
12
|
-
hasBottomPadding?: boolean;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
type SocialProps = {
|
|
16
|
-
type?: string;
|
|
17
|
-
url: string;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const Social = ({ type, url }: SocialProps) => {
|
|
21
|
-
let icon = type === 'website' || type == null ? 'earth-americas' : type;
|
|
22
|
-
if (
|
|
23
|
-
icon !== 'earth-americas' &&
|
|
24
|
-
icon !== 'discord' &&
|
|
25
|
-
icon !== 'facebook' &&
|
|
26
|
-
icon !== 'slack' &&
|
|
27
|
-
icon !== 'twitter' &&
|
|
28
|
-
icon !== 'github' &&
|
|
29
|
-
icon !== 'linkedin' &&
|
|
30
|
-
icon !== 'instagram' &&
|
|
31
|
-
icon !== 'youtube' &&
|
|
32
|
-
icon !== 'medium' &&
|
|
33
|
-
icon !== 'hacker-news'
|
|
34
|
-
) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const iconPrefix = isBrandFontAwesomeIcon(type) ? 'fab' : 'fas';
|
|
39
|
-
return (
|
|
40
|
-
<a href={url} className="hover:text-slate-500 dark:hover:text-slate-400">
|
|
41
|
-
<span className="sr-only">{type}</span>
|
|
42
|
-
<FontAwesomeIcon icon={[iconPrefix, icon]} className="h-6 p-1" />
|
|
43
|
-
</a>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export function Footer({ previous, next, hasBottomPadding = true }: FooterProps) {
|
|
48
|
-
return (
|
|
49
|
-
<footer className={clsx('text-sm leading-6', previous || next ? 'mt-12' : 'mt-16')}>
|
|
50
|
-
{(previous || next) && (
|
|
51
|
-
<div className="mb-10 text-slate-700 font-semibold flex items-center dark:text-slate-200">
|
|
52
|
-
{previous && (
|
|
53
|
-
<Link href={previous.href}>
|
|
54
|
-
<a className="group flex items-center hover:text-slate-900 dark:hover:text-white">
|
|
55
|
-
<svg
|
|
56
|
-
viewBox="0 0 3 6"
|
|
57
|
-
className="mr-3 w-auto h-1.5 text-slate-400 overflow-visible group-hover:text-slate-600 dark:group-hover:text-slate-300"
|
|
58
|
-
>
|
|
59
|
-
<path
|
|
60
|
-
d="M3 0L0 3L3 6"
|
|
61
|
-
fill="none"
|
|
62
|
-
stroke="currentColor"
|
|
63
|
-
strokeWidth="2"
|
|
64
|
-
strokeLinecap="round"
|
|
65
|
-
strokeLinejoin="round"
|
|
66
|
-
/>
|
|
67
|
-
</svg>
|
|
68
|
-
{previous.title}
|
|
69
|
-
</a>
|
|
70
|
-
</Link>
|
|
71
|
-
)}
|
|
72
|
-
{next && (
|
|
73
|
-
<Link href={next.href}>
|
|
74
|
-
<a className="group ml-auto flex items-center hover:text-slate-900 dark:hover:text-white">
|
|
75
|
-
{next.title}
|
|
76
|
-
<svg
|
|
77
|
-
viewBox="0 0 3 6"
|
|
78
|
-
className="ml-3 w-auto h-1.5 text-slate-400 overflow-visible group-hover:text-slate-600 dark:group-hover:text-slate-300"
|
|
79
|
-
>
|
|
80
|
-
<path
|
|
81
|
-
d="M0 0L3 3L0 6"
|
|
82
|
-
fill="none"
|
|
83
|
-
stroke="currentColor"
|
|
84
|
-
strokeWidth="2"
|
|
85
|
-
strokeLinecap="round"
|
|
86
|
-
strokeLinejoin="round"
|
|
87
|
-
/>
|
|
88
|
-
</svg>
|
|
89
|
-
</a>
|
|
90
|
-
</Link>
|
|
91
|
-
)}
|
|
92
|
-
</div>
|
|
93
|
-
)}
|
|
94
|
-
<div
|
|
95
|
-
className={clsx(
|
|
96
|
-
'pt-10 border-t border-slate-200 sm:flex justify-between text-slate-500 dark:border-slate-200/5',
|
|
97
|
-
{ 'pb-28': hasBottomPadding }
|
|
98
|
-
)}
|
|
99
|
-
>
|
|
100
|
-
<div className="mb-6 sm:mb-0 sm:flex">
|
|
101
|
-
<p>
|
|
102
|
-
<Link href="https://mintlify.com">
|
|
103
|
-
<a target="_blank" className="hover:text-slate-900 dark:hover:text-slate-400">
|
|
104
|
-
Powered by Mintlify
|
|
105
|
-
</a>
|
|
106
|
-
</Link>
|
|
107
|
-
</p>
|
|
108
|
-
</div>
|
|
109
|
-
<div className="flex space-x-6 text-slate-400 dark:text-slate-500">
|
|
110
|
-
{config?.footerSocials &&
|
|
111
|
-
Array.isArray(config.footerSocials) &&
|
|
112
|
-
config.footerSocials.map((social) => (
|
|
113
|
-
<Social key={social.url} url={social.url} type={social?.type} />
|
|
114
|
-
))}
|
|
115
|
-
{config?.footerSocials &&
|
|
116
|
-
typeof config.footerSocials === 'object' &&
|
|
117
|
-
Object.entries(config.footerSocials).map(([socialType, socialUrl]) => (
|
|
118
|
-
<Social key={socialUrl} url={socialUrl} type={socialType} />
|
|
119
|
-
))}
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
</footer>
|
|
123
|
-
);
|
|
124
|
-
}
|