From 7eddf996e38ad572f183531ac2ae7d82d5f8371b Mon Sep 17 00:00:00 2001 From: bholmesdev Date: Mon, 6 Mar 2023 10:05:59 -0500 Subject: [PATCH] fix: move validateComponents to render comp --- .../markdoc/components/Renderer.astro | 4 ++ .../markdoc/components/astroNode.ts | 39 +------------------ packages/integrations/markdoc/src/utils.ts | 34 ++++++++++++++++ 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/packages/integrations/markdoc/components/Renderer.astro b/packages/integrations/markdoc/components/Renderer.astro index 2079a5168..4a78fda95 100644 --- a/packages/integrations/markdoc/components/Renderer.astro +++ b/packages/integrations/markdoc/components/Renderer.astro @@ -1,6 +1,7 @@ --- import type { RenderableTreeNode } from '@markdoc/markdoc'; import type { AstroInstance } from 'astro'; +import { validateComponentsProp } from '../dist/utils.js'; import { createAstroNode } from './astroNode'; import RenderNode from './RenderNode.astro'; @@ -10,6 +11,9 @@ type Props = { }; const { content, components } = Astro.props as Props; + +// Will throw if components is invalid +validateComponentsProp(components); --- diff --git a/packages/integrations/markdoc/components/astroNode.ts b/packages/integrations/markdoc/components/astroNode.ts index da0ccbd21..12a0cd0a6 100644 --- a/packages/integrations/markdoc/components/astroNode.ts +++ b/packages/integrations/markdoc/components/astroNode.ts @@ -1,8 +1,7 @@ import type { AstroInstance } from 'astro'; import type { RenderableTreeNode } from '@markdoc/markdoc'; import Markdoc from '@markdoc/markdoc'; -import { MarkdocError } from '../dist/utils.js'; -import z from 'astro/zod'; +import { MarkdocError, isCapitalized } from '../dist/utils.js'; export type AstroNode = | string @@ -21,15 +20,13 @@ export function createAstroNode( node: RenderableTreeNode, components: Record = {} ): AstroNode { - components = validateComponentsProp(components); - if (typeof node === 'string' || typeof node === 'number') { return String(node); } else if (node === null || typeof node !== 'object' || !Markdoc.Tag.isTag(node)) { return ''; } - if (isCapitalized(node.name) && node.name in components) { + if (node.name in components) { const component = components[node.name]; const props = node.attributes; const children = node.children.map((child) => createAstroNode(child, components)); @@ -52,35 +49,3 @@ export function createAstroNode( }; } } - -const componentsPropValidator = z.record( - z - .string() - .min(1, 'Invalid `components` prop. Component names cannot be empty!') - .refine( - (value) => isCapitalized(value), - (value) => ({ - message: `Invalid \`components\` prop: ${JSON.stringify( - value - )}. Component name must be capitalized. If you want to render HTML elements as components, try using a Markdoc node [TODO: DOCS LINK]`, - }) - ), - z.any() -); - -function validateComponentsProp(components: Record) { - try { - return componentsPropValidator.parse(components); - } catch (e) { - throw new MarkdocError({ - message: - e instanceof z.ZodError - ? e.issues[0].message - : 'Invalid `components` prop. Ensure you are passing an object of components to ', - }); - } -} - -function isCapitalized(str: string) { - return str.length > 0 && str[0] === str[0].toUpperCase(); -} diff --git a/packages/integrations/markdoc/src/utils.ts b/packages/integrations/markdoc/src/utils.ts index e4150075b..d9d728a09 100644 --- a/packages/integrations/markdoc/src/utils.ts +++ b/packages/integrations/markdoc/src/utils.ts @@ -2,6 +2,8 @@ import matter from 'gray-matter'; import path from 'node:path'; import type fsMod from 'node:fs'; import type { ErrorPayload as ViteErrorPayload } from 'vite'; +import type { AstroInstance } from 'astro'; +import z from 'astro/zod'; /** * Match YAML exception handling from Astro core errors @@ -109,3 +111,35 @@ export function getAstroConfigPath(fs: typeof fsMod, root: string): string | und export function prependForwardSlash(str: string) { return str[0] === '/' ? str : '/' + str; } + +export function validateComponentsProp(components: Record) { + try { + return componentsPropValidator.parse(components); + } catch (e) { + throw new MarkdocError({ + message: + e instanceof z.ZodError + ? e.issues[0].message + : 'Invalid `components` prop. Ensure you are passing an object of components to ', + }); + } +} + +const componentsPropValidator = z.record( + z + .string() + .min(1, 'Invalid `components` prop. Component names cannot be empty!') + .refine( + (value) => isCapitalized(value), + (value) => ({ + message: `Invalid \`components\` prop: ${JSON.stringify( + value + )}. Component name must be capitalized. If you want to render HTML elements as components, try using a Markdoc node [TODO: DOCS LINK]`, + }) + ), + z.any() +); + +export function isCapitalized(str: string) { + return str.length > 0 && str[0] === str[0].toUpperCase(); +}