Throw Error for WIP Features
This commit is contained in:
parent
3c1fcc237d
commit
cf2e3b31cb
5 changed files with 50 additions and 209 deletions
|
@ -10,84 +10,9 @@ interface InternalProps extends Props {
|
|||
$scope: string;
|
||||
}
|
||||
|
||||
const __TopLevelAstro = {
|
||||
site: new URL("http://localhost:3000"),
|
||||
fetchContent: (globResult) => fetchContent(globResult, import.meta.url),
|
||||
resolve(...segments) {
|
||||
return segments.reduce(
|
||||
(url, segment) => new URL(segment, url),
|
||||
new URL("http://localhost:3000/packages/astro/components/Markdown.astro")
|
||||
).pathname
|
||||
},
|
||||
};
|
||||
const Astro = __TopLevelAstro;
|
||||
|
||||
export interface Props {
|
||||
content?: string;
|
||||
}
|
||||
|
||||
// Internal props that should not be part of the external interface.
|
||||
interface InternalProps extends Props {
|
||||
$scope: string;
|
||||
}
|
||||
|
||||
const __TopLevelAstro = {
|
||||
site: new URL("http://localhost:3000"),
|
||||
fetchContent: (globResult) => fetchContent(globResult, import.meta.url),
|
||||
resolve(...segments) {
|
||||
return segments.reduce(
|
||||
(url, segment) => new URL(segment, url),
|
||||
new URL("http://localhost:3000/packages/astro/components/Markdown.astro")
|
||||
).pathname
|
||||
},
|
||||
};
|
||||
const Astro = __TopLevelAstro;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
// `__render()`: Render the contents of the Astro module.
|
||||
import { h, Fragment } from 'astro/runtime/h.js';
|
||||
const __astroInternal = Symbol('astro.internal');
|
||||
const __astroContext = Symbol.for('astro.context');
|
||||
async function __render(props, ...children) {
|
||||
const Astro = Object.create(__TopLevelAstro, {
|
||||
props: {
|
||||
value: props,
|
||||
enumerable: true
|
||||
},
|
||||
pageCSS: {
|
||||
value: (props[__astroContext] && props[__astroContext].pageCSS) || [],
|
||||
enumerable: true
|
||||
},
|
||||
isPage: {
|
||||
value: (props[__astroInternal] && props[__astroInternal].isPage) || false,
|
||||
enumerable: true
|
||||
},
|
||||
request: {
|
||||
value: (props[__astroContext] && props[__astroContext].request) || {},
|
||||
enumerable: true
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
content,
|
||||
$scope
|
||||
} = Astro.props;
|
||||
let html = null;
|
||||
|
||||
// This flow is only triggered if a user passes `<Markdown content={content} />`
|
||||
if (content) {
|
||||
const { content: htmlContent } = await renderMarkdown(content, {
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
|
||||
import fetch from 'node-fetch';
|
||||
import loadLanguages from 'prismjs/components/index.js';
|
||||
import { addAstro } from '@astrojs/prism';
|
||||
---
|
||||
import Prism from 'prismjs';
|
||||
|
||||
if(!('fetch' in globalThis)) {
|
||||
globalThis.fetch = fetch;
|
||||
}
|
||||
import { addAstro } from '@astrojs/prism';
|
||||
import loadLanguages from 'prismjs/components/index.js';
|
||||
|
||||
export interface Props {
|
||||
class?: string;
|
||||
|
@ -18,128 +13,40 @@ const { class: className, lang, code } = Astro.props as Props;
|
|||
|
||||
let classLanguage = `language-${lang}`
|
||||
|
||||
const __TopLevelAstro = {
|
||||
site: new URL("http://localhost:3000"),
|
||||
fetchContent: (globResult) => fetchContent(globResult, import.meta.url),
|
||||
resolve(...segments) {
|
||||
return segments.reduce(
|
||||
(url, segment) => new URL(segment, url),
|
||||
new URL("http://localhost:3000/packages/astro/components/Prism.astro")
|
||||
).pathname
|
||||
},
|
||||
};
|
||||
const Astro = __TopLevelAstro;
|
||||
const languageMap = new Map([
|
||||
['ts', 'typescript']
|
||||
]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// `__render()`: Render the contents of the Astro module.
|
||||
import { h, Fragment } from 'astro/runtime/h.js';
|
||||
const __astroInternal = Symbol('astro.internal');
|
||||
const __astroContext = Symbol.for('astro.context');
|
||||
async function __render(props, ...children) {
|
||||
const Astro = Object.create(__TopLevelAstro, {
|
||||
props: {
|
||||
value: props,
|
||||
enumerable: true
|
||||
},
|
||||
pageCSS: {
|
||||
value: (props[__astroContext] && props[__astroContext].pageCSS) || [],
|
||||
enumerable: true
|
||||
},
|
||||
isPage: {
|
||||
value: (props[__astroInternal] && props[__astroInternal].isPage) || false,
|
||||
enumerable: true
|
||||
},
|
||||
request: {
|
||||
value: (props[__astroContext] && props[__astroContext].request) || {},
|
||||
enumerable: true
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
class: className,
|
||||
lang,
|
||||
code
|
||||
} = Astro.props;
|
||||
let classLanguage = `language-${lang}`;
|
||||
const languageMap = new Map([["ts", "typescript"]]);
|
||||
if (lang == null) {
|
||||
console.warn("Prism.astro: No language provided.");
|
||||
console.warn('Prism.astro: No language provided.');
|
||||
}
|
||||
const ensureLoaded = (lang2) => {
|
||||
if (lang2 && !Prism.languages[lang2]) {
|
||||
loadLanguages([lang2]);
|
||||
|
||||
const ensureLoaded = lang => {
|
||||
if(lang && !Prism.languages[lang]) {
|
||||
loadLanguages([lang]);
|
||||
}
|
||||
};
|
||||
|
||||
if(languageMap.has(lang)) {
|
||||
ensureLoaded(languageMap.get(lang));
|
||||
} else if (lang === "astro") {
|
||||
ensureLoaded("typescript");
|
||||
} else if(lang === 'astro') {
|
||||
ensureLoaded('typescript');
|
||||
addAstro(Prism);
|
||||
} else {
|
||||
ensureLoaded("markup-templating");
|
||||
ensureLoaded('markup-templating'); // Prism expects this to exist for a number of other langs
|
||||
ensureLoaded(lang);
|
||||
}
|
||||
|
||||
if(lang && !Prism.languages[lang]) {
|
||||
console.warn(`Unable to load the language: ${lang}`);
|
||||
}
|
||||
|
||||
const grammar = Prism.languages[lang];
|
||||
let html = code;
|
||||
if (grammar) {
|
||||
html = Prism.highlight(code, grammar, lang);
|
||||
}
|
||||
|
||||
return h(Fragment, null, h(Fragment, null,h("pre", {"class":([className, classLanguage].join(" ")),[__astroContext]:props[__astroContext]},h("code", {"class":(classLanguage),[__astroContext]:props[__astroContext]},(html)))));
|
||||
}
|
||||
export default { isAstroComponent: true, __render };
|
||||
|
||||
// `__renderPage()`: Render the contents of the Astro module as a page. This is a special flow,
|
||||
// triggered by loading a component directly by URL.
|
||||
export async function __renderPage({request, children, props, css}) {
|
||||
const currentChild = {
|
||||
isAstroComponent: true,
|
||||
layout: typeof __layout === 'undefined' ? undefined : __layout,
|
||||
content: typeof __content === 'undefined' ? undefined : __content,
|
||||
__render,
|
||||
};
|
||||
|
||||
const isLayout = (__astroContext in props);
|
||||
if(!isLayout) {
|
||||
let astroRootUIDCounter = 0;
|
||||
Object.defineProperty(props, __astroContext, {
|
||||
value: {
|
||||
pageCSS: css,
|
||||
request,
|
||||
createAstroRootUID(seed) { return seed + astroRootUIDCounter++; },
|
||||
},
|
||||
writable: false,
|
||||
enumerable: false
|
||||
});
|
||||
}
|
||||
|
||||
Object.defineProperty(props, __astroInternal, {
|
||||
value: {
|
||||
isPage: !isLayout
|
||||
},
|
||||
writable: false,
|
||||
enumerable: false
|
||||
});
|
||||
|
||||
const childBodyResult = await currentChild.__render(props, children);
|
||||
|
||||
// find layout, if one was given.
|
||||
if (currentChild.layout) {
|
||||
return currentChild.layout({
|
||||
request,
|
||||
props: {content: currentChild.content, [__astroContext]: props[__astroContext]},
|
||||
children: [childBodyResult],
|
||||
});
|
||||
}
|
||||
|
||||
return childBodyResult;
|
||||
};
|
||||
|
||||
|
||||
---
|
||||
|
||||
<pre class={[className, classLanguage].join(' ')}><code class={classLanguage}>{html}</code></pre>
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
export { default as Code } from './Code.astro';
|
||||
export { default as Debug } from './Debug.astro';
|
||||
export { default as Markdown } from './Markdown.astro';
|
||||
export { default as Prism } from './Prism.astro';
|
||||
// export { default as Code } from './Code.astro';
|
||||
// export { default as Debug } from './Debug.astro';
|
||||
// export { default as Markdown } from './Markdown.astro';
|
||||
// export { default as Prism } from './Prism.astro';
|
||||
|
||||
export const Code = () => {
|
||||
throw new Error(`Cannot render <Code />. "astro/components" are still WIP!`)
|
||||
}
|
||||
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!`)
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
"string-width": "^5.0.0",
|
||||
"strip-ansi": "^7.0.1",
|
||||
"supports-esm": "^1.0.0",
|
||||
"tiny-glob": "^0.2.8",
|
||||
"vite": "^2.5.7",
|
||||
"yargs-parser": "^20.2.9",
|
||||
"zod": "^3.8.1"
|
||||
|
|
|
@ -10,7 +10,7 @@ import { fileURLToPath } from 'url';
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { renderPage } from './astro.js';
|
||||
import { fdir } from 'fdir';
|
||||
import glob from 'tiny-glob';
|
||||
import { generatePaginateFunction } from './paginate.js';
|
||||
import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from './routing.js';
|
||||
import { parseNpmName, canonicalURL as getCanonicalURL, codeFrame } from './util.js';
|
||||
|
@ -176,7 +176,7 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
|||
const Component = await mod.default;
|
||||
const ext = path.posix.extname(filePath.pathname);
|
||||
if (!Component)
|
||||
throw new Error(`Expected an exported Astro component but recieved typeof ${typeof Component}`);
|
||||
throw new Error(`Expected an exported Astro component but received typeof ${typeof Component}`);
|
||||
|
||||
if (!Component.isAstroComponentFactory) throw new Error(`Unable to SSR non-Astro component (${route?.component})`);
|
||||
|
||||
|
@ -201,24 +201,19 @@ export async function ssr({ astroConfig, filePath, logging, mode, origin, pathna
|
|||
}
|
||||
|
||||
const createFetchContent = (currentFilePath: string) => {
|
||||
const fetchContentCache = new Map<string, any>();
|
||||
return async (pattern: string) => {
|
||||
const cwd = path.dirname(currentFilePath);
|
||||
const crawler = new fdir().glob(pattern);
|
||||
const files = await crawler.crawlWithOptions(cwd, {
|
||||
resolvePaths: true,
|
||||
includeBasePath: true,
|
||||
filters: [(p) => p !== currentFilePath]
|
||||
}).withPromise() as PathsOutput;
|
||||
|
||||
const cacheKey = `${cwd}:${pattern}`;
|
||||
if (fetchContentCache.has(cacheKey)) {
|
||||
return fetchContentCache.get(cacheKey);
|
||||
}
|
||||
const files = await glob(pattern, { cwd, absolute: true });
|
||||
const contents = await Promise.all(files.map(async file => {
|
||||
const { default: ChildComponent } = (await viteServer.ssrLoadModule(file)) as ComponentInstance;
|
||||
return renderPage({
|
||||
...result,
|
||||
createAstro: (props: any) => {
|
||||
return { props }
|
||||
},
|
||||
}, ChildComponent, {}, null);
|
||||
const { metadata: astro = {}, frontmatter = {} } = (await viteServer.ssrLoadModule(file)) as any;
|
||||
return { ...frontmatter, astro };
|
||||
}))
|
||||
fetchContentCache.set(cacheKey, contents);
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue