mirror of
https://github.com/supabase/supabase.git
synced 2026-05-08 18:00:20 -04:00
cf3ecc93eb
strictNullChecks was off for docs, which lets errors slip through and leads to incorrect required/optional typing on Zod-inferred types. This PR enables strictNullChecks and fixes all the existing violations.
142 lines
4.2 KiB
TypeScript
142 lines
4.2 KiB
TypeScript
import type { Content, Paragraph, Root } from 'mdast'
|
|
import type { MdxJsxFlowElement } from 'mdast-util-mdx'
|
|
import type { Node } from 'unist'
|
|
import { visit } from 'unist-util-visit'
|
|
|
|
/**
|
|
* Transforms PyMdown Tabs to Supabase Tabs.
|
|
*
|
|
* https://facelessuser.github.io/pymdown-extensions/extensions/tabbed/
|
|
*/
|
|
const remarkPyMdownTabs = function () {
|
|
return function transformer(root: Root) {
|
|
visit(root, 'paragraph', (node: Paragraph, nodeIndex: number, parent: Root) => {
|
|
for (let i = 0; i < node.children.length; i++) {
|
|
const child = node.children[i]
|
|
if (child.type !== 'text') {
|
|
continue
|
|
}
|
|
|
|
// Look for 3 '=', followed by an optionally quoted title,
|
|
// followed by optional newlines of text
|
|
const match = child.value.match(/^\n*=== ("?)(.+)\1\n?((?:.|\n)*)/)
|
|
|
|
if (!match) {
|
|
continue
|
|
}
|
|
|
|
// Extract the tab title along with the remaining text
|
|
const [, , title, value] = match
|
|
|
|
// Rewrite the node's value to remove the tab syntax
|
|
child.value = value
|
|
|
|
// Extract sibling nodes that should be linked to this tab
|
|
const siblingsToNest = extractLinkedSiblings(parent, node, nodeIndex)
|
|
|
|
const children: any[] = [...node.children.slice(i), ...siblingsToNest]
|
|
|
|
const tabPanelElement: MdxJsxFlowElement = {
|
|
type: 'mdxJsxFlowElement',
|
|
name: 'TabPanel',
|
|
attributes: [
|
|
{
|
|
type: 'mdxJsxAttribute',
|
|
name: 'id',
|
|
value: title,
|
|
},
|
|
{
|
|
type: 'mdxJsxAttribute',
|
|
name: 'label',
|
|
value: title,
|
|
},
|
|
],
|
|
children,
|
|
}
|
|
|
|
let nodesAdded = 0
|
|
const previousNode = parent.children[nodeIndex - 1]
|
|
|
|
if (previousNode?.type === 'mdxJsxFlowElement' && previousNode.name === 'Tabs') {
|
|
// Add TabPanel to existing Tabs component
|
|
previousNode.children.push(tabPanelElement)
|
|
|
|
// Remove this node
|
|
parent.children.splice(nodeIndex, 1)
|
|
nodesAdded--
|
|
} else {
|
|
// Create new Tabs components and add TabPanel
|
|
const tabsElement: MdxJsxFlowElement = {
|
|
type: 'mdxJsxFlowElement',
|
|
name: 'Tabs',
|
|
attributes: [
|
|
{
|
|
type: 'mdxJsxAttribute',
|
|
name: 'scrollable',
|
|
},
|
|
{
|
|
type: 'mdxJsxAttribute',
|
|
name: 'size',
|
|
value: 'small',
|
|
},
|
|
{
|
|
type: 'mdxJsxAttribute',
|
|
name: 'type',
|
|
value: 'underlined',
|
|
},
|
|
],
|
|
children: [tabPanelElement],
|
|
}
|
|
|
|
// Overwrite this paragraph node with Tabs component
|
|
parent.children.splice(nodeIndex, 1, tabsElement)
|
|
}
|
|
|
|
// If this wasn't the first child of the paragraph, create
|
|
// a new paragraph before this with the previous text children
|
|
if (i > 0) {
|
|
const previousChildren = node.children.slice(0, i)
|
|
const paragraph: Paragraph = {
|
|
type: 'paragraph',
|
|
children: previousChildren,
|
|
}
|
|
parent.children.splice(nodeIndex, 0, paragraph)
|
|
|
|
nodesAdded++
|
|
}
|
|
|
|
// Return the correct index for the next visit, since
|
|
// we may have added or removed an element in the array
|
|
return nodeIndex + nodesAdded
|
|
}
|
|
})
|
|
|
|
return root
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Identifies sibling nodes that should be linked to this admonition
|
|
* based on their indent level (ie. 4 spaces).
|
|
*
|
|
* Iterates through proceeding siblings until one is found that is
|
|
* not indented relative to the original node.
|
|
*
|
|
* Splices the discovered siblings out of the original parent and returns them.
|
|
*/
|
|
function extractLinkedSiblings(parent: Root, node: Node, index: number, indentAmount = 4) {
|
|
if (!node.position) return []
|
|
const { column } = node.position.start
|
|
|
|
let nextSibling: Content
|
|
let i = index
|
|
|
|
do {
|
|
nextSibling = parent.children[++i]
|
|
} while (nextSibling?.position && nextSibling.position.start.column === column + indentAmount)
|
|
|
|
return parent.children.splice(index + 1, i - index - 1)
|
|
}
|
|
|
|
export default remarkPyMdownTabs
|