From ec1800a5c2867e2f8afd371e047be796871c2e36 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 23 Jan 2024 14:41:15 +0100 Subject: [PATCH] airbyte-lib: Connector documentation (#33063) --- docusaurus/docusaurus.config.js | 3 +- docusaurus/package.json | 3 + docusaurus/pnpm-lock.yaml | 92 +++++++++ .../src/components/AirbyteLibExample.jsx | 34 ++++ .../src/components/HeaderDecoration.jsx | 3 + docusaurus/src/components/SpecSchema.jsx | 187 ++++++++++++++++++ .../src/components/SpecSchema.module.css | 84 ++++++++ docusaurus/src/connector_registry.js | 11 ++ docusaurus/src/remark/docsHeaderDecoration.js | 15 +- docusaurus/src/remark/specDecoration.js | 24 +++ docusaurus/src/theme/MDXComponents/index.js | 4 + 11 files changed, 446 insertions(+), 14 deletions(-) create mode 100644 docusaurus/src/components/AirbyteLibExample.jsx create mode 100644 docusaurus/src/components/SpecSchema.jsx create mode 100644 docusaurus/src/components/SpecSchema.module.css create mode 100644 docusaurus/src/connector_registry.js create mode 100644 docusaurus/src/remark/specDecoration.js diff --git a/docusaurus/docusaurus.config.js b/docusaurus/docusaurus.config.js index c81b245c62b3..f655750e599c 100644 --- a/docusaurus/docusaurus.config.js +++ b/docusaurus/docusaurus.config.js @@ -11,6 +11,7 @@ const darkCodeTheme = themes.dracula; const docsHeaderDecoration = require("./src/remark/docsHeaderDecoration"); const productInformation = require("./src/remark/productInformation"); +const specDecoration = require("./src/remark/specDecoration"); const redirects = yaml.load( fs.readFileSync(path.join(__dirname, "redirects.yml"), "utf-8") @@ -89,7 +90,7 @@ const config = { editUrl: "https://github.com/airbytehq/airbyte/blob/master/docs", path: "../docs", exclude: ["**/*.inapp.md"], - remarkPlugins: [docsHeaderDecoration, productInformation], + remarkPlugins: [docsHeaderDecoration, productInformation, specDecoration], }, blog: false, theme: { diff --git a/docusaurus/package.json b/docusaurus/package.json index 2f6b8fe15705..2b76eecf0b61 100644 --- a/docusaurus/package.json +++ b/docusaurus/package.json @@ -90,6 +90,7 @@ "@fortawesome/free-regular-svg-icons": "^6.5.1", "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", + "@headlessui/react": "^1.7.18", "@mdx-js/react": "^3.0.0", "async": "2.6.4", "autoprefixer": "10.4.16", @@ -105,6 +106,7 @@ "docusaurus-plugin-hubspot": "^1.0.0", "docusaurus-plugin-segment": "^1.0.3", "js-yaml": "^4.1.0", + "json-schema-faker": "^0.5.4", "node-fetch": "^3.3.2", "nth-check": "2.0.1", "postcss-convert-values": "6.0.1", @@ -121,6 +123,7 @@ "react-dom": "^18.2.0", "react-markdown": "^8.0.7", "react-router": "5.3.3", + "sanitize-html": "^2.11.0", "sockjs": "0.3.24", "trim": "0.0.3", "unist-builder": "^4.0.0", diff --git a/docusaurus/pnpm-lock.yaml b/docusaurus/pnpm-lock.yaml index ab5603ec5d4d..39706c103c09 100644 --- a/docusaurus/pnpm-lock.yaml +++ b/docusaurus/pnpm-lock.yaml @@ -233,6 +233,9 @@ dependencies: '@fortawesome/react-fontawesome': specifier: ^0.2.0 version: 0.2.0(@fortawesome/fontawesome-svg-core@6.5.1)(react@18.2.0) + '@headlessui/react': + specifier: ^1.7.18 + version: 1.7.18(react-dom@18.2.0)(react@18.2.0) '@mdx-js/react': specifier: ^3.0.0 version: 3.0.0(@types/react@18.2.46)(react@18.2.0) @@ -278,6 +281,9 @@ dependencies: js-yaml: specifier: ^4.1.0 version: 4.1.0 + json-schema-faker: + specifier: ^0.5.4 + version: 0.5.4 node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -326,6 +332,9 @@ dependencies: react-router: specifier: 5.3.3 version: 5.3.3(react@18.2.0) + sanitize-html: + specifier: ^2.11.0 + version: 2.11.0 sockjs: specifier: 0.3.24 version: 0.3.24 @@ -3037,6 +3046,19 @@ packages: '@hapi/hoek': 9.3.0 dev: false + /@headlessui/react@1.7.18(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ==} + engines: {node: '>=10'} + peerDependencies: + react: ^16 || ^17 || ^18 + react-dom: ^16 || ^17 || ^18 + dependencies: + '@tanstack/react-virtual': 3.0.1(react-dom@18.2.0)(react@18.2.0) + client-only: 0.0.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@jest/schemas@29.6.3: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3411,6 +3433,21 @@ packages: defer-to-connect: 2.0.1 dev: false + /@tanstack/react-virtual@3.0.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-IFOFuRUTaiM/yibty9qQ9BfycQnYXIDHGP2+cU+0LrFFGNhVxCXSQnaY6wkX8uJVteFEBjUondX0Hmpp7TNcag==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@tanstack/virtual-core': 3.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@tanstack/virtual-core@3.0.0: + resolution: {integrity: sha512-SYXOBTjJb05rXa2vl55TTwO40A6wKu0R5i1qQwhJYNDIqaIGF7D0HsLw+pJAyi2OvntlEIVusx3xtbbgSUi6zg==} + dev: false + /@trysound/sax@0.2.0: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -4272,6 +4309,10 @@ packages: set-function-length: 1.1.1 dev: false + /call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + dev: false + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -4433,6 +4474,10 @@ packages: '@colors/colors': 1.5.0 dev: false + /client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: false + /clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} @@ -6077,6 +6122,10 @@ packages: engines: {node: '>= 14.17'} dev: false + /format-util@1.0.5: + resolution: {integrity: sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg==} + dev: false + /format@0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} @@ -7059,6 +7108,23 @@ packages: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: false + /json-schema-faker@0.5.4: + resolution: {integrity: sha512-DdRRnRNSxkQVXEsUUXzAtvBpsROZHvM59/LQcV6+3gQVMvaeMsqfNKN3ivRwaiahTW7pvxa+LJfOaPP+nhFo4g==} + hasBin: true + dependencies: + json-schema-ref-parser: 6.1.0 + jsonpath-plus: 7.2.0 + dev: false + + /json-schema-ref-parser@6.1.0: + resolution: {integrity: sha512-pXe9H1m6IgIpXmE5JSb8epilNTGsmTb2iPohAXpOdhqGFbQjNeHHsZxU+C8w6T81GZxSPFLeUoqDJmzxx5IGuw==} + deprecated: Please switch to @apidevtools/json-schema-ref-parser + dependencies: + call-me-maybe: 1.0.2 + js-yaml: 3.14.1 + ono: 4.0.11 + dev: false + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: false @@ -7081,6 +7147,11 @@ packages: graceful-fs: 4.2.11 dev: false + /jsonpath-plus@7.2.0: + resolution: {integrity: sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==} + engines: {node: '>=12.0.0'} + dev: false + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -8396,6 +8467,12 @@ packages: mimic-fn: 2.1.0 dev: false + /ono@4.0.11: + resolution: {integrity: sha512-jQ31cORBFE6td25deYeD80wxKBMj+zBmHTrVxnc6CKhx8gho6ipmWM5zj/oeoqioZ99yqBls9Z/9Nss7J26G2g==} + dependencies: + format-util: 1.0.5 + dev: false + /open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -8528,6 +8605,10 @@ packages: resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} dev: false + /parse-srcset@1.0.2: + resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} + dev: false + /parse5-htmlparser2-tree-adapter@7.0.0: resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} dependencies: @@ -10099,6 +10180,17 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: false + /sanitize-html@2.11.0: + resolution: {integrity: sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==} + dependencies: + deepmerge: 4.3.1 + escape-string-regexp: 4.0.0 + htmlparser2: 8.0.2 + is-plain-object: 5.0.0 + parse-srcset: 1.0.2 + postcss: 8.4.32 + dev: false + /sax@1.3.0: resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} dev: false diff --git a/docusaurus/src/components/AirbyteLibExample.jsx b/docusaurus/src/components/AirbyteLibExample.jsx new file mode 100644 index 000000000000..aeb78fbf0813 --- /dev/null +++ b/docusaurus/src/components/AirbyteLibExample.jsx @@ -0,0 +1,34 @@ +import React from "react"; +import { JSONSchemaFaker } from "json-schema-faker"; +import CodeBlock from '@theme/CodeBlock'; + + +export const AirbyteLibExample = ({ + specJSON, + connector +}) => { + const spec = JSON.parse(specJSON); + const fakeConfig = JSONSchemaFaker.generate(spec); + return <> +

+ Install the Python library via: +

+ {"pip install airbyte-lib"} +

Then, execute a sync by loading the connector like this:

+ {`import airbyte_lib as ab + +config = ${JSON.stringify(fakeConfig, null, 2)} + +result = ab.get_connector( + "${connector}", + config=config, +).read_all() + +for record in result.cache.streams["my_stream:name"]: + print(record)`} +

You can find more information in the airbyte_lib quickstart guide.

+ ; +}; diff --git a/docusaurus/src/components/HeaderDecoration.jsx b/docusaurus/src/components/HeaderDecoration.jsx index 49d1d9ad7e05..e4ebdc918f52 100644 --- a/docusaurus/src/components/HeaderDecoration.jsx +++ b/docusaurus/src/components/HeaderDecoration.jsx @@ -27,6 +27,7 @@ const CROSS_ICON = ( export const HeaderDecoration = ({ isOss: isOssString, isCloud: isCloudString, + isPypiPublished: isPypiPublishedString, dockerImageTag, supportLevel, iconUrl, @@ -36,6 +37,7 @@ export const HeaderDecoration = ({ }) => { const isOss = isOssString.toUpperCase() === "TRUE"; const isCloud = isCloudString.toUpperCase() === "TRUE"; + const isPypiPublished = isPypiPublishedString.toUpperCase() === "TRUE"; return ( <> @@ -49,6 +51,7 @@ export const HeaderDecoration = ({ {isOss ? CHECK_ICON : CROSS_ICON} Airbyte OSS + {isPypiPublished && {CHECK_ICON} airbyte_lib}
diff --git a/docusaurus/src/components/SpecSchema.jsx b/docusaurus/src/components/SpecSchema.jsx new file mode 100644 index 000000000000..23ac1cc5104c --- /dev/null +++ b/docusaurus/src/components/SpecSchema.jsx @@ -0,0 +1,187 @@ +import React from "react"; +import styles from "./SpecSchema.module.css"; +import sanitizeHtml from "sanitize-html"; +import { Disclosure } from "@headlessui/react"; +import Heading from '@theme/Heading'; +import className from 'classnames'; + +export const SpecSchema = ({ + specJSON +}) => { + const spec = JSON.parse(specJSON); + spec.description = undefined; + spec.title = "Config fields"; + return <> + + ; +}; + +function JSONSchemaViewer(props) { + return
+ Config fields reference +
+
+ Field +
+
+ Type +
+
+ Title +
+ +
+
+} + +function getOrderedProperties(schema) { + if (!schema.properties) { + return []; + } + const requiredProperties = new Set(schema.required || []); + return Object.entries(schema.properties).sort(([a], [b]) => { + // Sort required properties first, then respect the order of the schema + if (requiredProperties.has(a) && !requiredProperties.has(b)) { + return -1; + } + else if (requiredProperties.has(b) && !requiredProperties.has(a)) { + return 1; + } + else { + return 0; + } + }); +} + +function JSONSchemaObject(props) { + const requiredProperties = new Set(props.schema.required || []); + return <> + {getOrderedProperties(props.schema).map(([key, schema]) => { + return + })} + +} + +function JSONSchemaOneOf(props) { + return <> +
    + {props.schema.oneOf.map((schema, i) => { + return
  • + +
  • + })} +
+ +} + +function isOneOf(schema) { + return schema.type === "object" && schema.oneOf; +} + +function isObjectArray(schema) { + return schema.type === "array" && schema.items && schema.items.type === "object"; +} + +function showCollapsible(schema) { + return (schema.type === "array" && schema.items && schema.items.type !== "object") || (schema.type === "object" && schema.properties) || showDescription(schema) +} + +function showDescription(schema) { + return typeof schema.default !== "undefined" || schema.pattern || schema.examples || schema.description || isOneOf(schema); +} + +function getIndentStyle(depth) { + return { + paddingLeft: `${depth * 13}px` + }; +} + +function getType(schema) { + if (schema.const) { + return JSON.stringify(schema.const); + } + if (schema.type === "array" && schema.items) { + return `${schema.type}<${schema.items.type}>`; + } + return schema.type; +} + +function JSONSchemaProperty({ propertyKey, schema, required, depth = 0 }) { + const newDepth = depth + 1; + const propertyName = <> +
{propertyKey || schema.title}
+ {required &&
required
} + ; + const typeAndTitle = <> +
+ {getType(schema)} +
+
+ {schema.title &&
{schema.title}
} +
+ ; + if (showCollapsible(schema)) { + return + {({ open }) => ( + <> + +
+ {propertyName} +
+ {typeAndTitle} + + {showDescription(schema) && } + {schema.type === "object" && schema.oneOf && } + {schema.type === "object" && schema.properties && } + {schema.type === "array" && } + + )} +
+ } else { + return <> +
+ {propertyName} +
+ {typeAndTitle} + + } +} + +function Description({ schema, style }) { + return
+ {(typeof schema.default !== "undefined" && !schema.const) &&
Default:
{JSON.stringify(schema.default, null, 2)}
} + {schema.const &&
Constant value:
{JSON.stringify(schema.const, null, 2)}
} + {schema.pattern &&
Pattern{schema.pattern_descriptor && <> ({schema.pattern_descriptor})}:
{schema.pattern}
} + {(schema.examples && schema.examples.length > 1) &&
Examples:
    + {schema.examples.map((example, i) =>
  • {JSON.stringify(example)}
  • )} +
} + {(schema.examples && schema.examples.length === 1) &&
Example:
{JSON.stringify(schema.examples[0])}
} + {schema.description &&
} + {isOneOf(schema) && + One of:} + {isObjectArray(schema) && Item properties:} +
+} + +const allowedAttributes = { + ...sanitizeHtml.defaults.allowedAttributes, + a: [...sanitizeHtml.defaults.allowedAttributes.a, "rel"], +}; + +const TextWithHTML = ({ text, className }) => { + if (!text) { + return null; + } + + const sanitizedHtmlText = sanitizeHtml(text, { + allowedAttributes, + transformTags: { + a: sanitizeHtml.simpleTransform("a", { + target: "_blank", + rel: "noopener noreferrer", + }), + }, + }); + + return ; +}; diff --git a/docusaurus/src/components/SpecSchema.module.css b/docusaurus/src/components/SpecSchema.module.css new file mode 100644 index 000000000000..720c9d84979a --- /dev/null +++ b/docusaurus/src/components/SpecSchema.module.css @@ -0,0 +1,84 @@ +.block { + display: contents; +} + +.contents { + display: contents; +} + +.open { + transform: rotate(90deg); +} + +.clickable { + cursor: pointer; +} + +.propertyName { + font-weight: bold; +} + +.tag { + font-size: 0.8em; + padding: 2px 4px; + border-radius: 4px; + background-color: #c5c5c5; +} + +.oneOfList { + list-style: none; + margin: 0; + padding: 0; +} + +.oneOfHeader { + margin-bottom: 0; + margin-top: 10px; +} + +.grid { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + + background: var(--ifm-table-border-color); + gap: 1px; + border: 1px solid var(--ifm-table-border-color); +} + +.headerItem { + grid-row: span 1; + grid-column: span 1; + background-color: white; + text-align: left; + align-items: center; + + display: flex; + flex-direction: row; + gap: 10px; + border: none; + padding: 0; + font-size: inherit; + padding: 7px; +} + +.tableHeader { + background-color: #eee; + font-weight: bold; + border-bottom: 1px solid var(--ifm-table-border-color); + padding: 7px; +} + +.contentItem { + grid-row: span 1; + grid-column: span 1; + background-color: white; + padding: 7px; +} + +.descriptionItem { + grid-row: span 1; + grid-column: span 3; + background-color: white; + margin: 0; + padding: 7px; +} diff --git a/docusaurus/src/connector_registry.js b/docusaurus/src/connector_registry.js new file mode 100644 index 000000000000..f0468706f607 --- /dev/null +++ b/docusaurus/src/connector_registry.js @@ -0,0 +1,11 @@ +const REGISTRY_URL = + "https://connectors.airbyte.com/files/generated_reports/connector_registry_report.json"; + +const fetchCatalog = async () => { + console.log("Fetching connector registry..."); + const json = await fetch(REGISTRY_URL).then((resp) => resp.json()); + console.log(`fetched ${json.length} connectors form registry`); + return json; +}; + +module.exports = fetchCatalog(); \ No newline at end of file diff --git a/docusaurus/src/remark/docsHeaderDecoration.js b/docusaurus/src/remark/docsHeaderDecoration.js index 92e2c02d8f50..46281999d85e 100644 --- a/docusaurus/src/remark/docsHeaderDecoration.js +++ b/docusaurus/src/remark/docsHeaderDecoration.js @@ -1,17 +1,5 @@ -const fetch = require("node-fetch"); const visit = require("unist-util-visit").visit; - -const REGISTRY_URL = - "https://connectors.airbyte.com/files/generated_reports/connector_registry_report.json"; - -const fetchCatalog = async () => { - console.log("Fetching connector registry..."); - const json = await fetch(REGISTRY_URL).then((resp) => resp.json()); - console.log(`fetched ${json.length} connectors form registry`); - return json; -}; - -const catalog = fetchCatalog(); +const catalog = require("../connector_registry"); const toAttributes = (props) => Object.entries(props).map(([key, value]) => ({ @@ -54,6 +42,7 @@ const plugin = () => { node.attributes = toAttributes({ isOss: registryEntry.is_oss, isCloud: registryEntry.is_cloud, + isPypiPublished: Boolean(registryEntry.remoteRegistries?.pypi?.enabled), supportLevel: registryEntry.supportLevel_oss, dockerImageTag: registryEntry.dockerImageTag_oss, iconUrl: registryEntry.iconUrl_oss, diff --git a/docusaurus/src/remark/specDecoration.js b/docusaurus/src/remark/specDecoration.js new file mode 100644 index 000000000000..ef205bb4c764 --- /dev/null +++ b/docusaurus/src/remark/specDecoration.js @@ -0,0 +1,24 @@ +const visit = require("unist-util-visit").visit; +const catalog = require("../connector_registry"); + +const plugin = () => { + const transformer = async (ast, vfile) => { + + const registry = await catalog; + + visit(ast, "mdxJsxFlowElement", (node) => { + if (node.name !== "SpecSchema" && node.name !== "AirbyteLibExample") return; + + const connectorName = node.attributes.find((attr) => attr.name === "connector").value; + const connectorSpec = registry.find( (c) => c.dockerRepository_oss === `airbyte/${connectorName}`).spec_oss.connectionSpecification; + node.attributes.push({ + type: "mdxJsxAttribute", + name: "specJSON", + value: JSON.stringify(connectorSpec) + }); + }); + }; + return transformer; +}; + +module.exports = plugin; diff --git a/docusaurus/src/theme/MDXComponents/index.js b/docusaurus/src/theme/MDXComponents/index.js index e2b4da7359e5..88510a7ffa09 100644 --- a/docusaurus/src/theme/MDXComponents/index.js +++ b/docusaurus/src/theme/MDXComponents/index.js @@ -5,6 +5,8 @@ import { AppliesTo } from "@site/src/components/AppliesTo"; import { FieldAnchor } from "@site/src/components/FieldAnchor"; import { HideInUI } from "@site/src/components/HideInUI"; import { HeaderDecoration } from "@site/src/components/HeaderDecoration"; +import { SpecSchema } from "@site/src/components/SpecSchema"; +import { AirbyteLibExample } from "@site/src/components/AirbyteLibExample"; import { ProductInformation } from "@site/src/components/ProductInformation"; import { Arcade } from "@site/src/components/Arcade"; @@ -16,5 +18,7 @@ export default { FieldAnchor, HideInUI, HeaderDecoration, + SpecSchema, + AirbyteLibExample, ProductInformation, };