WIP: markdown support
This commit is contained in:
parent
f0839c62df
commit
ce1b160bf9
15 changed files with 143 additions and 128 deletions
|
@ -2,10 +2,10 @@
|
|||
// Component Imports
|
||||
import { Markdown } from 'astro/components';
|
||||
import Layout from '../layouts/main.astro';
|
||||
import ReactCounter from '../components/ReactCounter.jsx';
|
||||
import PreactCounter from '../components/PreactCounter.tsx';
|
||||
import VueCounter from '../components/VueCounter.vue';
|
||||
import SvelteCounter from '../components/SvelteCounter.svelte';
|
||||
// import ReactCounter from '../components/ReactCounter.jsx';
|
||||
// import PreactCounter from '../components/PreactCounter.tsx';
|
||||
// import VueCounter from '../components/VueCounter.vue';
|
||||
// import SvelteCounter from '../components/SvelteCounter.svelte';
|
||||
|
||||
// Component Script:
|
||||
// You can write any JavaScript/TypeScript that you'd like here.
|
||||
|
@ -32,10 +32,10 @@ const items = ['A', 'B', 'C'];
|
|||
|
||||
## Embed framework components
|
||||
|
||||
<ReactCounter client:visible />
|
||||
<PreactCounter client:visible />
|
||||
<VueCounter client:visible />
|
||||
<SvelteCounter client:visible />
|
||||
<!-- <ReactCounter client:visible /> -->
|
||||
<!-- <PreactCounter client:visible /> -->
|
||||
<!-- <VueCounter client:visible /> -->
|
||||
<!-- <SvelteCounter client:visible /> -->
|
||||
|
||||
## Use Expressions
|
||||
|
||||
|
@ -43,11 +43,11 @@ const items = ['A', 'B', 'C'];
|
|||
|
||||
## Oh yeah...
|
||||
|
||||
<ReactCounter client:visible>
|
||||
<!-- <ReactCounter client:visible>
|
||||
🤯 It's also _recursive_!
|
||||
|
||||
### Markdown can be embedded in any child component
|
||||
</ReactCounter>
|
||||
</ReactCounter> -->
|
||||
|
||||
## Code
|
||||
|
||||
|
|
|
@ -1,32 +1,39 @@
|
|||
---
|
||||
import { renderMarkdown } from '@astrojs/markdown-remark';
|
||||
import { dedent } from './utils.js';
|
||||
|
||||
export interface Props {
|
||||
content?: string;
|
||||
// export interface Props {
|
||||
// content?: string;
|
||||
// }
|
||||
|
||||
// // Internal props that should not be part of the external interface.
|
||||
// interface InternalProps extends Props {
|
||||
// $scope: string;
|
||||
// }
|
||||
|
||||
// const { content, $scope } = Astro.props as InternalProps;
|
||||
// let html = null;
|
||||
|
||||
// // This flow is only triggered if a user passes `<Markdown content={content} />`
|
||||
// if (content) {
|
||||
// const { content: htmlContent } = await renderMarkdown(content, {
|
||||
// mode: 'md',
|
||||
// $: {
|
||||
// scopedClassName: $scope
|
||||
// }
|
||||
// });
|
||||
// html = htmlContent;
|
||||
// }
|
||||
|
||||
const { content = await $$slots.default() } = Astro.props;
|
||||
let markdown = typeof content === 'string' ? content : await content.render();
|
||||
markdown = dedent(markdown);
|
||||
|
||||
let html: string;
|
||||
try {
|
||||
({ code: html } = await renderMarkdown(markdown));
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
// Internal props that should not be part of the external interface.
|
||||
interface InternalProps extends Props {
|
||||
$scope: string;
|
||||
}
|
||||
|
||||
const { content, $scope } = Astro.props as InternalProps;
|
||||
let html = null;
|
||||
|
||||
// This flow is only triggered if a user passes `<Markdown content={content} />`
|
||||
if (content) {
|
||||
const { content: htmlContent } = await renderMarkdown(content, {
|
||||
mode: 'md',
|
||||
$: {
|
||||
scopedClassName: $scope
|
||||
}
|
||||
});
|
||||
html = htmlContent;
|
||||
}
|
||||
|
||||
/*
|
||||
If we have rendered `html` for `content`, render that
|
||||
Otherwise, just render the slotted content
|
||||
*/
|
||||
---
|
||||
{html ? html : <slot />}
|
||||
{html}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// export { default as Code } from './Code.astro';
|
||||
// export { default as Debug } from './Debug.astro';
|
||||
// export { default as Markdown } from './Markdown.astro';
|
||||
export { default as Markdown } from './Markdown.astro';
|
||||
// export { default as Prism } from './Prism.astro';
|
||||
|
||||
export const Code = () => {
|
||||
|
@ -9,9 +9,6 @@ export const Code = () => {
|
|||
export const Debug = () => {
|
||||
throw new Error(`Cannot render <Debug />. "astro/components" are still WIP!`)
|
||||
}
|
||||
export const Markdown = () => {
|
||||
throw new Error(`Cannot render <Markdown />. "astro/components" are still WIP!`)
|
||||
}
|
||||
export const Prism = () => {
|
||||
throw new Error(`Cannot render <Prism />. "astro/components" are still WIP!`)
|
||||
}
|
||||
|
|
48
packages/astro/components/utils.js
Normal file
48
packages/astro/components/utils.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
export function dedent(
|
||||
strings,
|
||||
...values
|
||||
) {
|
||||
// $FlowFixMe: Flow doesn't undestand .raw
|
||||
const raw = typeof strings === "string" ? [strings] : strings.raw;
|
||||
|
||||
// first, perform interpolation
|
||||
let result = "";
|
||||
for (let i = 0; i < raw.length; i++) {
|
||||
result += raw[i]
|
||||
// join lines when there is a suppressed newline
|
||||
.replace(/\\\n[ \t]*/g, "")
|
||||
// handle escaped backticks
|
||||
.replace(/\\`/g, "`");
|
||||
|
||||
if (i < values.length) {
|
||||
result += values[i];
|
||||
}
|
||||
}
|
||||
|
||||
// now strip indentation
|
||||
const lines = result.split("\n");
|
||||
let mindent = null;
|
||||
lines.forEach(l => {
|
||||
let m = l.match(/^(\s+)\S+/);
|
||||
if (m) {
|
||||
let indent = m[1].length;
|
||||
if (!mindent) {
|
||||
// this is the first indented line
|
||||
mindent = indent;
|
||||
} else {
|
||||
mindent = Math.min(mindent, indent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (mindent !== null) {
|
||||
const m = mindent; // appease Flow
|
||||
result = lines.map(l => l[0] === " " ? l.slice(m) : l).join("\n");
|
||||
}
|
||||
|
||||
return result
|
||||
// dedent eats leading and trailing whitespace too
|
||||
.trim()
|
||||
// handle escaped newlines at the end to ensure they don't get stripped too
|
||||
.replace(/\\n/g, "\n");
|
||||
}
|
|
@ -54,7 +54,7 @@
|
|||
"connect": "^3.7.0",
|
||||
"del": "^6.0.0",
|
||||
"es-module-lexer": "^0.7.1",
|
||||
"esbuild": "^0.12.28",
|
||||
"esbuild": "0.12.28",
|
||||
"estree-util-value-to-estree": "^1.2.0",
|
||||
"fast-xml-parser": "^3.19.0",
|
||||
"html-entities": "^2.3.2",
|
||||
|
@ -69,14 +69,14 @@
|
|||
"shiki": "^0.9.10",
|
||||
"shorthash": "^0.0.2",
|
||||
"slash": "^4.0.0",
|
||||
"srcset-parse": "^1.1.0",
|
||||
"source-map": "^0.7.3",
|
||||
"sourcemap-codec": "^1.4.8",
|
||||
"srcset-parse": "^1.1.0",
|
||||
"string-width": "^5.0.0",
|
||||
"strip-ansi": "^7.0.1",
|
||||
"supports-esm": "^1.0.0",
|
||||
"tiny-glob": "^0.2.8",
|
||||
"vite": "^2.5.10",
|
||||
"vite": "2.6.2",
|
||||
"yargs-parser": "^20.2.9",
|
||||
"zod": "^3.8.1"
|
||||
},
|
||||
|
|
|
@ -54,6 +54,10 @@ export class AstroComponent {
|
|||
this.expressions = expressions;
|
||||
}
|
||||
|
||||
public render() {
|
||||
return renderAstroComponent(this);
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
const { htmlParts, expressions } = this;
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@ export async function loadViteConfig(
|
|||
});
|
||||
const userDevDeps = Object.keys(packageJSON?.devDependencies || {});
|
||||
const { external, noExternal } = await viteSSRDeps([...userDeps, ...userDevDeps]);
|
||||
// console.log(external.has('tiny-glob'), noExternal.has('tiny-glob'));
|
||||
|
||||
// console.log(external);
|
||||
|
||||
// load Astro renderers
|
||||
await Promise.all(
|
||||
|
@ -99,13 +100,20 @@ export async function loadViteConfig(
|
|||
/** Note: SSR API is in beta (https://vitejs.dev/guide/ssr.html) */
|
||||
ssr: {
|
||||
external: [...external],
|
||||
noExternal: [...noExternal],
|
||||
noExternal: [],
|
||||
},
|
||||
},
|
||||
viteConfig
|
||||
);
|
||||
}
|
||||
|
||||
const MANUAL_NO_EXTERNAL = new Set([
|
||||
'astro',
|
||||
'@astrojs/markdown-remark',
|
||||
'micromark-factory-mdx-expression',
|
||||
'remark',
|
||||
])
|
||||
|
||||
/** Try and automatically figure out Vite external & noExternal */
|
||||
async function viteSSRDeps(deps: string[]): Promise<{ external: Set<string>; noExternal: Set<string> }> {
|
||||
const skip = new Set<string>();
|
||||
|
@ -149,26 +157,15 @@ async function viteSSRDeps(deps: string[]): Promise<{ external: Set<string>; noE
|
|||
return;
|
||||
}
|
||||
|
||||
// sort this package
|
||||
let isExternal = true; // external by default
|
||||
|
||||
// ESM gets noExternal
|
||||
if (packageJSON.type === 'module') isExternal = false;
|
||||
// TODO: manual bugfixes for Vite
|
||||
if (pkg.name === '@sveltejs/vite-plugin-svelte') isExternal = true;
|
||||
if (pkg.name === 'micromark-util-events-to-acorn') isExternal = true;
|
||||
if (pkg.name === 'unified') isExternal = true;
|
||||
// TODO: add more checks here if needed
|
||||
|
||||
// add to list
|
||||
if (isExternal === true) {
|
||||
external.add(spec);
|
||||
} else {
|
||||
if (packageJSON.type === 'module' || MANUAL_NO_EXTERNAL.has(spec) || spec.startsWith('node:')) {
|
||||
noExternal.add(spec);
|
||||
} else {
|
||||
external.add(spec);
|
||||
}
|
||||
|
||||
// recursively load dependencies for package (but not devDeps)
|
||||
await Promise.all(Object.keys(packageJSON.dependencies || {}).map(sortPkg));
|
||||
await Promise.all(Object.keys(packageJSON.dependencies || {}).map(spec => sortPkg(spec)));
|
||||
} catch (err) {
|
||||
// can’t load package: skip
|
||||
skip.add(spec);
|
||||
|
|
|
@ -22,10 +22,10 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {
|
|||
|
||||
// 2. Transform from `.md` to valid `.astro`
|
||||
let render = config.markdownOptions.render;
|
||||
let renderOpts = {};
|
||||
let renderOpts = { mode: "mdx" };
|
||||
if (Array.isArray(render)) {
|
||||
render = render[0];
|
||||
renderOpts = render[1];
|
||||
renderOpts = render[1] || renderOpts;
|
||||
}
|
||||
if (typeof render === 'string') {
|
||||
({ default: render } = await import(render));
|
||||
|
|
|
@ -23,6 +23,7 @@ export function rehypeCodeBlock() {
|
|||
const escapeCode = (code: Element): void => {
|
||||
code.children = code.children.map((child) => {
|
||||
if (child.type === 'text') {
|
||||
// return { ...child };
|
||||
return { ...child, value: `{\`${child.value.replace(/\$\{/g, '\\$\\{').replace(/`/g, '\\`')}\`}` };
|
||||
}
|
||||
return child;
|
||||
|
|
|
@ -2,19 +2,21 @@ import type { AstroMarkdownOptions, MarkdownRenderingOptions } from './types';
|
|||
|
||||
import createCollectHeaders from './rehype-collect-headers.js';
|
||||
import scopedStyles from './remark-scoped-styles.js';
|
||||
import { remarkExpressions, loadRemarkExpressions } from './remark-expressions.js';
|
||||
import { remarkExpressions } from './remark-expressions.js';
|
||||
import rehypeExpressions from './rehype-expressions.js';
|
||||
import { remarkJsx, loadRemarkJsx } from './remark-jsx.js';
|
||||
import { remarkJsx } from './remark-jsx.js';
|
||||
import rehypeJsx from './rehype-jsx.js';
|
||||
import { remarkCodeBlock, rehypeCodeBlock } from './codeblock.js';
|
||||
import remarkSlug from './remark-slug.js';
|
||||
import { loadPlugins } from './load-plugins.js';
|
||||
|
||||
import { unified } from 'unified';
|
||||
import markdown from 'remark-parse';
|
||||
import markdownToHtml from 'remark-rehype';
|
||||
import rehypeStringify from 'rehype-stringify';
|
||||
import matter from 'gray-matter';
|
||||
import { unified } from 'unified';
|
||||
import rehypeStringify from 'rehype-stringify';
|
||||
import remarkGFM from 'remark-gfm';
|
||||
import remarkFootnotes from 'remark-footnotes';
|
||||
|
||||
export { AstroMarkdownOptions, MarkdownRenderingOptions };
|
||||
|
||||
|
@ -25,9 +27,9 @@ export async function renderMarkdownWithFrontmatter(contents: string, opts?: Mar
|
|||
return { ...value, frontmatter };
|
||||
}
|
||||
|
||||
export const DEFAULT_REMARK_PLUGINS = [
|
||||
'remark-gfm',
|
||||
'remark-footnotes',
|
||||
export const DEFAULT_REMARK_PLUGINS: any[] = [
|
||||
remarkGFM,
|
||||
remarkFootnotes,
|
||||
// TODO: reenable smartypants!
|
||||
// '@silvenon/remark-smartypants'
|
||||
]
|
||||
|
@ -38,11 +40,9 @@ export const DEFAULT_REHYPE_PLUGINS = [
|
|||
|
||||
/** Shared utility for rendering markdown */
|
||||
export async function renderMarkdown(content: string, opts?: MarkdownRenderingOptions | null) {
|
||||
const { remarkPlugins = DEFAULT_REMARK_PLUGINS, rehypePlugins = DEFAULT_REHYPE_PLUGINS } = opts ?? {};
|
||||
const { remarkPlugins = DEFAULT_REMARK_PLUGINS, rehypePlugins = DEFAULT_REHYPE_PLUGINS, mode = 'md' } = opts ?? {};
|
||||
const { headers, rehypeCollectHeaders } = createCollectHeaders();
|
||||
|
||||
await Promise.all([loadRemarkExpressions(), loadRemarkJsx()]); // Vite bug: dynamically import() these because of CJS interop (this will cache)
|
||||
|
||||
let parser = unified()
|
||||
.use(markdown)
|
||||
.use([remarkJsx])
|
||||
|
@ -72,11 +72,12 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp
|
|||
try {
|
||||
const vfile = await parser
|
||||
.use(rehypeCollectHeaders)
|
||||
.use(rehypeCodeBlock)
|
||||
.use([rehypeCodeBlock, { mode }])
|
||||
.use(rehypeStringify, { allowParseErrors: true, preferUnquoted: true, allowDangerousHtml: true })
|
||||
.process(content);
|
||||
result = vfile.toString();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Vite bug: dynamically import() modules needed for CJS. Cache in memory to keep side effects
|
||||
let mdxExpression: any;
|
||||
let mdxExpressionFromMarkdown: any;
|
||||
let mdxExpressionToMarkdown: any;
|
||||
import { mdxExpression } from 'micromark-extension-mdx-expression';
|
||||
import { mdxExpressionFromMarkdown, mdxExpressionToMarkdown } from 'mdast-util-mdx-expression';
|
||||
|
||||
export function remarkExpressions(this: any, options: any) {
|
||||
let settings = options || {};
|
||||
|
@ -17,15 +16,3 @@ export function remarkExpressions(this: any, options: any) {
|
|||
else data[field] = [value];
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadRemarkExpressions() {
|
||||
if (!mdxExpression) {
|
||||
const micromarkMdxExpression = await import('micromark-extension-mdx-expression');
|
||||
mdxExpression = micromarkMdxExpression.mdxExpression;
|
||||
}
|
||||
if (!mdxExpressionFromMarkdown || !mdxExpressionToMarkdown) {
|
||||
const mdastUtilMdxExpression = await import('mdast-util-mdx-expression');
|
||||
mdxExpressionFromMarkdown = mdastUtilMdxExpression.mdxExpressionFromMarkdown;
|
||||
mdxExpressionToMarkdown = mdastUtilMdxExpression.mdxExpressionToMarkdown;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Vite bug: dynamically import() modules needed for CJS. Cache in memory to keep side effects
|
||||
let mdxJsx: any;
|
||||
let mdxJsxFromMarkdown: any;
|
||||
let mdxJsxToMarkdown: any;
|
||||
import { mdxJsx } from 'micromark-extension-mdx-jsx';
|
||||
import { mdxJsxFromMarkdown, mdxJsxToMarkdown } from 'mdast-util-mdx-jsx';
|
||||
|
||||
export function remarkJsx(this: any, options: any) {
|
||||
let settings = options || {};
|
||||
|
@ -17,15 +16,3 @@ export function remarkJsx(this: any, options: any) {
|
|||
else data[field] = [value];
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadRemarkJsx() {
|
||||
if (!mdxJsx) {
|
||||
const micromarkMdxJsx = await import('micromark-extension-mdx-jsx');
|
||||
mdxJsx = micromarkMdxJsx.mdxJsx;
|
||||
}
|
||||
if (!mdxJsxFromMarkdown || !mdxJsxToMarkdown) {
|
||||
const mdastUtilMdxJsx = await import('mdast-util-mdx-jsx');
|
||||
mdxJsxFromMarkdown = mdastUtilMdxJsx.mdxJsxFromMarkdown;
|
||||
mdxJsxToMarkdown = mdastUtilMdxJsx.mdxJsxToMarkdown;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* @typedef {import('hast').Properties} Properties
|
||||
*/
|
||||
|
||||
import {toString} from 'mdast-util-to-string'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import { toString } from 'mdast-util-to-string'
|
||||
import { visit } from 'unist-util-visit'
|
||||
import BananaSlug from 'github-slugger'
|
||||
|
||||
const slugs = new BananaSlug()
|
||||
|
|
|
@ -4,6 +4,7 @@ export type UnifiedPluginImport = Promise<{ default: unified.Plugin }>;
|
|||
export type Plugin = string | [string, any] | UnifiedPluginImport | [UnifiedPluginImport, any];
|
||||
|
||||
export interface AstroMarkdownOptions {
|
||||
mode: 'md'|'mdx';
|
||||
remarkPlugins?: Plugin[];
|
||||
rehypePlugins?: Plugin[];
|
||||
}
|
||||
|
|
29
yarn.lock
29
yarn.lock
|
@ -3975,16 +3975,16 @@ es6-promisify@^5.0.0:
|
|||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
esbuild@0.12.28, esbuild@^0.12.17, esbuild@^0.12.28:
|
||||
version "0.12.28"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.28.tgz#84da0d2a0d0dee181281545271e0d65cf6fab1ef"
|
||||
integrity sha512-pZ0FrWZXlvQOATlp14lRSk1N9GkeJ3vLIwOcUoo3ICQn9WNR4rWoNi81pbn6sC1iYUy7QPqNzI3+AEzokwyVcA==
|
||||
|
||||
esbuild@^0.11.16:
|
||||
version "0.11.23"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.11.23.tgz#c42534f632e165120671d64db67883634333b4b8"
|
||||
integrity sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==
|
||||
|
||||
esbuild@^0.12.17, esbuild@^0.12.28:
|
||||
version "0.12.28"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.28.tgz#84da0d2a0d0dee181281545271e0d65cf6fab1ef"
|
||||
integrity sha512-pZ0FrWZXlvQOATlp14lRSk1N9GkeJ3vLIwOcUoo3ICQn9WNR4rWoNi81pbn6sC1iYUy7QPqNzI3+AEzokwyVcA==
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
|
@ -9421,7 +9421,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
|
|||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
source-map@~0.7.2:
|
||||
source-map@^0.7.3, source-map@~0.7.2:
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
||||
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
||||
|
@ -9516,21 +9516,6 @@ srcset-parse@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/srcset-parse/-/srcset-parse-1.1.0.tgz#73f787f38b73ede2c5af775e0a3465579488122b"
|
||||
integrity sha512-JWp4cG2eybkvKA1QUHGoNK6JDEYcOnSuhzNGjZuYUPqXreDl/VkkvP2sZW7Rmh+icuCttrR9ccb2WPIazyM/Cw==
|
||||
|
||||
sqlite3@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.2.tgz#00924adcc001c17686e0a6643b6cbbc2d3965083"
|
||||
integrity sha512-1SdTNo+BVU211Xj1csWa8lV6KM0CtucDwRyA0VHl91wEH1Mgh7RxUpI4rVvG7OhHrzCSGaVyW5g8vKvlrk9DJA==
|
||||
dependencies:
|
||||
node-addon-api "^3.0.0"
|
||||
node-pre-gyp "^0.11.0"
|
||||
optionalDependencies:
|
||||
node-gyp "3.x"
|
||||
|
||||
sqlite@^4.0.23:
|
||||
version "4.0.23"
|
||||
resolved "https://registry.yarnpkg.com/sqlite/-/sqlite-4.0.23.tgz#ada09028b38e91883db08ac465d841e814d1bb00"
|
||||
integrity sha512-dSdmSkrdIhUL7xP/fiEMfFuAo4dxb0afag3rK8T4Y9lYxE3g3fXT0J8H9qSFvmcKxnM0zEA8yvLbpdWQ8mom3g==
|
||||
|
||||
sshpk@^1.7.0:
|
||||
version "1.16.1"
|
||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
||||
|
@ -10659,7 +10644,7 @@ vfile@^5.0.0:
|
|||
unist-util-stringify-position "^3.0.0"
|
||||
vfile-message "^3.0.0"
|
||||
|
||||
vite@^2.5.10:
|
||||
vite@2.5.10:
|
||||
version "2.5.10"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-2.5.10.tgz#c598e3b5a7e1956ffc52eb3b3420d177fc2ed2a5"
|
||||
integrity sha512-0ObiHTi5AHyXdJcvZ67HMsDgVpjT5RehvVKv6+Q0jFZ7zDI28PF5zK9mYz2avxdA+4iJMdwCz6wnGNnn4WX5Gg==
|
||||
|
|
Loading…
Reference in a new issue