From a2ae7018ca83cb3c19e803fb813e76ceed730679 Mon Sep 17 00:00:00 2001 From: natemoo-re Date: Mon, 17 May 2021 14:30:21 +0000 Subject: [PATCH] [ci] yarn format --- docs/markdown.md | 8 ++- .../remote-markdown/src/components/Yell.jsx | 7 +- .../astro-parser/src/parse/state/codefence.ts | 2 +- .../astro-parser/src/parse/state/codespan.ts | 5 +- packages/astro/src/compiler/codegen/index.ts | 64 +++++++++---------- packages/astro/src/compiler/index.ts | 12 ++-- .../src/compiler/markdown/micromark.d.ts | 6 +- .../markdown/rehype-collect-headers.ts | 10 +-- .../src/compiler/markdown/remark-mdx-lite.ts | 16 ++--- .../compiler/markdown/remark-scoped-styles.ts | 4 +- .../astro/src/compiler/transform/styles.ts | 2 +- packages/astro/src/compiler/utils.ts | 11 ++-- packages/astro/src/frontend/markdown.ts | 22 +++---- .../astro/src/frontend/render/renderer.ts | 10 +-- packages/astro/src/frontend/render/utils.ts | 2 +- packages/astro/src/runtime.ts | 6 +- packages/astro/src/search.ts | 2 +- packages/astro/test/astro-markdown.test.js | 1 - packages/astro/test/plain-markdown.test.js | 1 - ...astro-markdown-language-configuration.json | 12 ++-- 20 files changed, 103 insertions(+), 100 deletions(-) diff --git a/docs/markdown.md b/docs/markdown.md index ceeb0b515..116f807a6 100644 --- a/docs/markdown.md +++ b/docs/markdown.md @@ -17,6 +17,7 @@ Astro treats any `.md` files inside of the `/src/pages` directory as pages. Thes The only special Frontmatter key is `layout`, which defines the relative path to a `.astro` component which should wrap your Markdown content. `src/pages/index.md` + ```md --- layout: ../layouts/main.astro @@ -30,6 +31,7 @@ Layout files are normal `.astro` components. Any Frontmatter defined in your `.m The rendered Markdown content is placed into the default `` element. `src/layouts/main.astro` + ```jsx --- export let content; @@ -52,7 +54,7 @@ Similar to tools like [MDX](https://mdxjs.com/) or [MDsveX](https://github.com/p Astro exposes a special `Markdown` component for `.astro` files which enables markdown syntax for its children **recursively**. Within the `Markdown` component you may also use plain HTML or any other type of component that is supported by Astro. -```jsx +````jsx --- // For now, this import _must_ be named "Markdown" and _must not_ be wrapped with a custom component // We're working on easing these restrictions! @@ -91,7 +93,7 @@ const expressions = 'Lorem ipsum'; -``` +```` ### Remote Markdown @@ -111,7 +113,7 @@ const content = await fetch('https://raw.githubusercontent.com/snowpackjs/snowpa ### Security FAQs -**Aren't there security concerns to rendering remote markdown directly to HTML?** +**Aren't there security concerns to rendering remote markdown directly to HTML?** Yes! Just like with regular HTML, improper use the `` component can open you up to a [cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) attack. If you are rendering untrusted content, be sure to _santize your content **before** rendering it_. diff --git a/examples/remote-markdown/src/components/Yell.jsx b/examples/remote-markdown/src/components/Yell.jsx index ae7d0d959..366d88a95 100644 --- a/examples/remote-markdown/src/components/Yell.jsx +++ b/examples/remote-markdown/src/components/Yell.jsx @@ -1,5 +1,10 @@ import { h, Fragment } from 'preact'; export default function Yell({ children }) { - return children.filter(v => typeof v === 'string').join('').toUpperCase() + '!' + return ( + children + .filter((v) => typeof v === 'string') + .join('') + .toUpperCase() + '!' + ); } diff --git a/packages/astro-parser/src/parse/state/codefence.ts b/packages/astro-parser/src/parse/state/codefence.ts index d5b498a0f..72867867c 100644 --- a/packages/astro-parser/src/parse/state/codefence.ts +++ b/packages/astro-parser/src/parse/state/codefence.ts @@ -23,7 +23,7 @@ export default function codefence(parser: Parser) { type: 'CodeFence', raw: `${raw}` + trailingWhitespace, metadata, - data + data, }; parser.current().children.push(node); diff --git a/packages/astro-parser/src/parse/state/codespan.ts b/packages/astro-parser/src/parse/state/codespan.ts index b685800a7..7f4b3354a 100644 --- a/packages/astro-parser/src/parse/state/codespan.ts +++ b/packages/astro-parser/src/parse/state/codespan.ts @@ -18,7 +18,10 @@ export default function codespan(parser: Parser) { end: parser.index, type: 'CodeSpan', raw, - data: raw?.slice(open?.length, open?.length * -1).replace(/^ /, '').replace(/ $/, '') + data: raw + ?.slice(open?.length, open?.length * -1) + .replace(/^ /, '') + .replace(/ $/, ''), }; parser.current().children.push(node); diff --git a/packages/astro/src/compiler/codegen/index.ts b/packages/astro/src/compiler/codegen/index.ts index ab66ee47d..64d7c1822 100644 --- a/packages/astro/src/compiler/codegen/index.ts +++ b/packages/astro/src/compiler/codegen/index.ts @@ -306,7 +306,7 @@ interface CodegenState { components: Components; css: string[]; markers: { - insideMarkdown: boolean|string; + insideMarkdown: boolean | string; }; importExportStatements: Set; dynamicImports: DynamicImportMap; @@ -583,41 +583,41 @@ function compileHtml(enterNode: TemplateNode, state: CodegenState, compileOption try { const attributes = getAttributes(node.attributes); - outSource += outSource === '' ? '' : ','; - if (node.type === 'Slot') { - outSource += `(children`; - return; - } - const COMPONENT_NAME_SCANNER = /^[A-Z]/; - if (!COMPONENT_NAME_SCANNER.test(name)) { - outSource += `h("${name}", ${attributes ? generateAttributes(attributes) : 'null'}`; - if (state.markers.insideMarkdown) { - outSource += `,h(__astroMarkdownRender, null` - } - return; - } - const [componentName, componentKind] = name.split(':'); - const componentImportData = components[componentName]; - if (!componentImportData) { - throw new Error(`Unknown Component: ${componentName}`); - } - if (componentImportData.type === '.astro') { - if (componentName === 'Markdown') { - const attributeStr = attributes ? generateAttributes(attributes) : 'null'; - state.markers.insideMarkdown = attributeStr; - outSource += `h(__astroMarkdownRender, ${attributeStr}` + outSource += outSource === '' ? '' : ','; + if (node.type === 'Slot') { + outSource += `(children`; return; } - } - const { wrapper, wrapperImport } = getComponentWrapper(name, components[componentName], { astroConfig, dynamicImports, filename }); - if (wrapperImport) { - importExportStatements.add(wrapperImport); - } + const COMPONENT_NAME_SCANNER = /^[A-Z]/; + if (!COMPONENT_NAME_SCANNER.test(name)) { + outSource += `h("${name}", ${attributes ? generateAttributes(attributes) : 'null'}`; + if (state.markers.insideMarkdown) { + outSource += `,h(__astroMarkdownRender, null`; + } + return; + } + const [componentName, componentKind] = name.split(':'); + const componentImportData = components[componentName]; + if (!componentImportData) { + throw new Error(`Unknown Component: ${componentName}`); + } + if (componentImportData.type === '.astro') { + if (componentName === 'Markdown') { + const attributeStr = attributes ? generateAttributes(attributes) : 'null'; + state.markers.insideMarkdown = attributeStr; + outSource += `h(__astroMarkdownRender, ${attributeStr}`; + return; + } + } + const { wrapper, wrapperImport } = getComponentWrapper(name, components[componentName], { astroConfig, dynamicImports, filename }); + if (wrapperImport) { + importExportStatements.add(wrapperImport); + } outSource += `h(${wrapper}, ${attributes ? generateAttributes(attributes) : 'null'}`; if (state.markers.insideMarkdown) { const attributeStr = state.markers.insideMarkdown; - outSource += `,h(__astroMarkdownRender, ${attributeStr}` + outSource += `,h(__astroMarkdownRender, ${attributeStr}`; } } catch (err) { // handle errors in scope with filename @@ -710,10 +710,10 @@ export async function codegen(ast: Ast, { compileOptions, filename }: CodeGenOpt components: {}, css: [], markers: { - insideMarkdown: false + insideMarkdown: false, }, importExportStatements: new Set(), - dynamicImports: new Map() + dynamicImports: new Map(), }; const { script, componentPlugins, createCollection } = compileModule(ast.module, state, compileOptions); diff --git a/packages/astro/src/compiler/index.ts b/packages/astro/src/compiler/index.ts index afdaac986..0eef6b5cd 100644 --- a/packages/astro/src/compiler/index.ts +++ b/packages/astro/src/compiler/index.ts @@ -48,13 +48,17 @@ async function convertAstroToJsx(template: string, opts: ConvertAstroOptions): P * .md -> .astro source */ export async function convertMdToAstroSource(contents: string, { filename }: { filename: string }): Promise { - const { content, frontmatter: { layout, ...frontmatter }, ...data } = await renderMarkdownWithFrontmatter(contents); + const { + content, + frontmatter: { layout, ...frontmatter }, + ...data + } = await renderMarkdownWithFrontmatter(contents); if (frontmatter['astro'] !== undefined) { throw new Error(`"astro" is a reserved word but was used as a frontmatter value!\n\tat ${filename}`); } const contentData: any = { ...frontmatter, - ...data + ...data, }; // can't be anywhere inside of a JS string, otherwise the HTML parser fails. // Break it up here so that the HTML parser won't detect it. @@ -75,7 +79,7 @@ async function convertMdToJsx( contents: string, { compileOptions, filename, fileID }: { compileOptions: CompileOptions; filename: string; fileID: string } ): Promise { -const raw = await convertMdToAstroSource(contents, { filename }); + const raw = await convertMdToAstroSource(contents, { filename }); const convertOptions = { compileOptions, filename, fileID }; return await convertAstroToJsx(raw, convertOptions); } @@ -105,7 +109,7 @@ export async function compileComponent( ): Promise { const result = await transformFromSource(source, { compileOptions, filename, projectRoot }); const site = compileOptions.astroConfig.buildOptions.site || `http://localhost:${compileOptions.astroConfig.devOptions.port}`; - const usesMarkdown = !!result.imports.find(spec => spec.indexOf('Markdown') > -1); + const usesMarkdown = !!result.imports.find((spec) => spec.indexOf('Markdown') > -1); // return template let modJsx = ` diff --git a/packages/astro/src/compiler/markdown/micromark.d.ts b/packages/astro/src/compiler/markdown/micromark.d.ts index 9c084f437..245b91fc1 100644 --- a/packages/astro/src/compiler/markdown/micromark.d.ts +++ b/packages/astro/src/compiler/markdown/micromark.d.ts @@ -1,11 +1,11 @@ -declare module '@silvenon/remark-smartypants' { +declare module '@silvenon/remark-smartypants' { export default function (): any; } -declare module 'mdast-util-mdx/from-markdown.js' { +declare module 'mdast-util-mdx/from-markdown.js' { export default function (): any; } -declare module 'mdast-util-mdx/to-markdown.js' { +declare module 'mdast-util-mdx/to-markdown.js' { export default function (): any; } diff --git a/packages/astro/src/compiler/markdown/rehype-collect-headers.ts b/packages/astro/src/compiler/markdown/rehype-collect-headers.ts index 3ebf3257d..edfcd29bc 100644 --- a/packages/astro/src/compiler/markdown/rehype-collect-headers.ts +++ b/packages/astro/src/compiler/markdown/rehype-collect-headers.ts @@ -7,16 +7,16 @@ export default function createCollectHeaders() { const visitor = (node: any) => { if (node.type !== 'element') return; - const { tagName, children } = node + const { tagName, children } = node; if (tagName[0] !== 'h') return; let [_, depth] = tagName.match(/h([0-6])/) ?? []; if (!depth) return; depth = Number.parseInt(depth); - + let text = ''; visit(node, 'text', (child) => { text += child.value; - }) + }); let slug = slugger.slug(text); node.properties = node.properties || {}; @@ -24,7 +24,7 @@ export default function createCollectHeaders() { headers.push({ depth, slug, text }); return node; - } + }; - return { headers, rehypeCollectHeaders: () => (tree: any) => visit(tree, visitor) } + return { headers, rehypeCollectHeaders: () => (tree: any) => visit(tree, visitor) }; } diff --git a/packages/astro/src/compiler/markdown/remark-mdx-lite.ts b/packages/astro/src/compiler/markdown/remark-mdx-lite.ts index 27eed917e..9ab8d764f 100644 --- a/packages/astro/src/compiler/markdown/remark-mdx-lite.ts +++ b/packages/astro/src/compiler/markdown/remark-mdx-lite.ts @@ -2,24 +2,24 @@ import fromMarkdown from 'mdast-util-mdx/from-markdown.js'; import toMarkdown from 'mdast-util-mdx/to-markdown.js'; /** See https://github.com/micromark/micromark-extension-mdx-md */ -const syntax = { disable: {null: ['autolink', 'codeIndented']} }; +const syntax = { disable: { null: ['autolink', 'codeIndented'] } }; -/** +/** * Lite version of https://github.com/mdx-js/mdx/tree/main/packages/remark-mdx * We don't need all the features MDX does because all components are precompiled * to HTML. We just want to disable a few MD features that cause issues. */ -function mdxLite (this: any) { - let data = this.data() +function mdxLite(this: any) { + let data = this.data(); add('micromarkExtensions', syntax); - add('fromMarkdownExtensions', fromMarkdown) - add('toMarkdownExtensions', toMarkdown) + add('fromMarkdownExtensions', fromMarkdown); + add('toMarkdownExtensions', toMarkdown); /** Adds remark plugin */ function add(field: string, value: any) { - if (data[field]) data[field].push(value) - else data[field] = [value] + if (data[field]) data[field].push(value); + else data[field] = [value]; } } diff --git a/packages/astro/src/compiler/markdown/remark-scoped-styles.ts b/packages/astro/src/compiler/markdown/remark-scoped-styles.ts index 9e2c8c290..7d19ae0ee 100644 --- a/packages/astro/src/compiler/markdown/remark-scoped-styles.ts +++ b/packages/astro/src/compiler/markdown/remark-scoped-styles.ts @@ -6,13 +6,13 @@ export default function scopedStyles(className: string) { const visitor = (node: any) => { if (noVisit.has(node.type)) return; - const {data} = node + const { data } = node; const currentClassName = data?.hProperties?.class ?? ''; node.data = node.data || {}; node.data.hProperties = node.data.hProperties || {}; node.data.hProperties.className = `${className} ${currentClassName}`.trim(); return node; - } + }; return () => (tree: any) => visit(tree, visitor); } diff --git a/packages/astro/src/compiler/transform/styles.ts b/packages/astro/src/compiler/transform/styles.ts index 10d9158a0..ab1d75ce2 100644 --- a/packages/astro/src/compiler/transform/styles.ts +++ b/packages/astro/src/compiler/transform/styles.ts @@ -214,7 +214,7 @@ export default function transformStyles({ compileOptions, filename, fileID }: Tr enter(node) { if (node.name !== 'Markdown') return; injectScopedClassAttribute(node, scopedClass, '$scope'); - } + }, }, Element: { enter(node) { diff --git a/packages/astro/src/compiler/utils.ts b/packages/astro/src/compiler/utils.ts index 701dc2adf..0fbc070f1 100644 --- a/packages/astro/src/compiler/utils.ts +++ b/packages/astro/src/compiler/utils.ts @@ -18,13 +18,10 @@ export interface MarkdownRenderingOptions { } /** Internal utility for rendering a full markdown file and extracting Frontmatter data */ -export async function renderMarkdownWithFrontmatter(contents: string, opts?: MarkdownRenderingOptions|null) { +export async function renderMarkdownWithFrontmatter(contents: string, opts?: MarkdownRenderingOptions | null) { // Dynamic import to ensure that "gray-matter" isn't built by Snowpack const { default: matter } = await import('gray-matter'); - const { - data: frontmatter, - content, - } = matter(contents); + const { data: frontmatter, content } = matter(contents); const value = await renderMarkdown(content, opts); return { ...value, frontmatter }; } @@ -41,12 +38,12 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp } if (useGfm) { - const {default:gfm} = await import('remark-gfm'); + const { default: gfm } = await import('remark-gfm'); parser = parser.use(gfm); } if (useFootnotes) { - const {default:footnotes} = await import('remark-footnotes'); + const { default: footnotes } = await import('remark-footnotes'); parser = parser.use(footnotes); } diff --git a/packages/astro/src/frontend/markdown.ts b/packages/astro/src/frontend/markdown.ts index 8fb013d76..2cae2a65b 100644 --- a/packages/astro/src/frontend/markdown.ts +++ b/packages/astro/src/frontend/markdown.ts @@ -1,14 +1,14 @@ import { renderMarkdown } from '../compiler/utils.js'; -/** - * Functional component which uses Astro's built-in Markdown rendering - * to render out its children. - * - * Note: the children have already been properly escaped/rendered - * by the parser and Astro, so at this point we're just rendering - * out plain markdown, no need for JSX support - */ -export default async function Markdown(props: { $scope: string|null }, ...children: string[]): Promise { +/** + * Functional component which uses Astro's built-in Markdown rendering + * to render out its children. + * + * Note: the children have already been properly escaped/rendered + * by the parser and Astro, so at this point we're just rendering + * out plain markdown, no need for JSX support + */ +export default async function Markdown(props: { $scope: string | null }, ...children: string[]): Promise { const { $scope = null } = props ?? {}; const text = dedent(children.join('').trimEnd()); let { content } = await renderMarkdown(text, { $: { scopedClassName: $scope } }); @@ -21,6 +21,6 @@ export default async function Markdown(props: { $scope: string|null }, ...childr /** Remove leading indentation based on first line */ function dedent(str: string) { let arr = str.match(/^[ \t]*(?=\S)/gm); - let first = !!arr && arr.find(x => x.length > 0)?.length; - return (!arr || !first) ? str : str.replace(new RegExp(`^[ \\t]{0,${first}}`, 'gm'), ''); + let first = !!arr && arr.find((x) => x.length > 0)?.length; + return !arr || !first ? str : str.replace(new RegExp(`^[ \\t]{0,${first}}`, 'gm'), ''); } diff --git a/packages/astro/src/frontend/render/renderer.ts b/packages/astro/src/frontend/render/renderer.ts index 86d74fa84..a7f6d165d 100644 --- a/packages/astro/src/frontend/render/renderer.ts +++ b/packages/astro/src/frontend/render/renderer.ts @@ -39,11 +39,11 @@ export function createRenderer(renderer: SupportedComponentRenderer) { const script = `${typeof wrapperStart === 'function' ? wrapperStart(innerContext) : wrapperStart} ${_imports(renderContext)} ${renderer.render({ - ...innerContext, - props: serializeProps(props), - children: `[${childrenToH(renderer, children) ?? ''}]`, - childrenAsString: `\`${children}\``, - })} + ...innerContext, + props: serializeProps(props), + children: `[${childrenToH(renderer, children) ?? ''}]`, + childrenAsString: `\`${children}\``, +})} ${typeof wrapperEnd === 'function' ? wrapperEnd(innerContext) : wrapperEnd}`; return [value, ``].join('\n'); diff --git a/packages/astro/src/frontend/render/utils.ts b/packages/astro/src/frontend/render/utils.ts index 29eaf64b5..64a712561 100644 --- a/packages/astro/src/frontend/render/utils.ts +++ b/packages/astro/src/frontend/render/utils.ts @@ -42,7 +42,7 @@ export const childrenToH = moize.deep(function childrenToH(renderer: ComponentRe const simpleTypes = new Set(['number', 'boolean']); const serializeChild = (child: unknown) => { - if (typeof child === 'string') return JSON.stringify(child).replace(/<\/script>/gmi, ''); + if (typeof child === 'string') return JSON.stringify(child).replace(/<\/script>/gim, ''); if (simpleTypes.has(typeof child)) return JSON.stringify(child); if (child === null) return `null`; if ((child as any).__SERIALIZED) return (child as any).__SERIALIZED; diff --git a/packages/astro/src/runtime.ts b/packages/astro/src/runtime.ts index 1eabbd364..965ea641a 100644 --- a/packages/astro/src/runtime.ts +++ b/packages/astro/src/runtime.ts @@ -314,11 +314,7 @@ async function createSnowpack(astroConfig: AstroConfig, options: CreateSnowpackO }, packageOptions: { knownEntrypoints: ['preact-render-to-string'], - external: [ - '@vue/server-renderer', - 'node-fetch', - 'prismjs/components/index.js' - ], + external: ['@vue/server-renderer', 'node-fetch', 'prismjs/components/index.js'], }, }); diff --git a/packages/astro/src/search.ts b/packages/astro/src/search.ts index 84a2ee634..20f600d31 100644 --- a/packages/astro/src/search.ts +++ b/packages/astro/src/search.ts @@ -45,7 +45,7 @@ export function searchForPage(url: URL, astroRoot: URL): SearchResult { // Try to find index.astro/md paths if (reqPath.endsWith('/')) { - const candidates = [`${base}index.astro`, `${base}index.md`,]; + const candidates = [`${base}index.astro`, `${base}index.md`]; const location = findAnyPage(candidates, astroRoot); if (location) { return { diff --git a/packages/astro/test/astro-markdown.test.js b/packages/astro/test/astro-markdown.test.js index f531ad2e5..edc18c576 100644 --- a/packages/astro/test/astro-markdown.test.js +++ b/packages/astro/test/astro-markdown.test.js @@ -8,7 +8,6 @@ const Markdown = suite('Astro Markdown tests'); setup(Markdown, './fixtures/astro-markdown'); setupBuild(Markdown, './fixtures/astro-markdown'); - Markdown('Can load markdown pages with Astro', async ({ runtime }) => { const result = await runtime.load('/post'); if (result.error) throw new Error(result.error); diff --git a/packages/astro/test/plain-markdown.test.js b/packages/astro/test/plain-markdown.test.js index 8e2f1a2ec..3adc904f5 100644 --- a/packages/astro/test/plain-markdown.test.js +++ b/packages/astro/test/plain-markdown.test.js @@ -34,5 +34,4 @@ Markdown('Builds markdown pages for prod', async (context) => { await context.build(); }); - Markdown.run(); diff --git a/tools/astro-vscode/languages/astro-markdown-language-configuration.json b/tools/astro-vscode/languages/astro-markdown-language-configuration.json index 1ee3bf7e2..c3242cb3b 100644 --- a/tools/astro-vscode/languages/astro-markdown-language-configuration.json +++ b/tools/astro-vscode/languages/astro-markdown-language-configuration.json @@ -16,13 +16,11 @@ { "open": "'", "close": "'" }, { "open": "\"", "close": "\"" }, { - "open": "<", - "close": ">", - "notIn": [ - "string" - ] - }, - { "open": "", "notIn": ["comment", "string"] }, + "open": "<", + "close": ">", + "notIn": ["string"] + }, + { "open": "", "notIn": ["comment", "string"] } ], "autoCloseBefore": ";:.,=}])>` \n\t", "surroundingPairs": [