diff --git a/apps/web/src/plugins/index.ts b/apps/web/src/plugins/index.ts deleted file mode 100644 index 1208d3aac8..0000000000 --- a/apps/web/src/plugins/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Astro plugins and remark plugins for enhanced markdown processing - */ - -import type { AstroIntegration } from 'astro' - -// Minimal AST node type for rehype/remark processing -interface AstNode { - type: string - children?: AstNode[] - value?: string - data?: Record -} - -function hasChildren(node: AstNode): node is AstNode & { children: AstNode[] } { - return Array.isArray(node.children) && node.children.length > 0 -} - -// Simple rehype heading IDs implementation -function rehypeHeadingIds() { - return (tree: AstNode) => { - // Simple implementation - add IDs to headings - function walk(node: AstNode) { - if (node.type === 'heading' && hasChildren(node)) { - const text = node.children - .map((child: AstNode) => child.value ?? '') - .join('') - if (text) { - node.data = node.data ?? {} - const hProperties = - (node.data['hProperties'] as Record) ?? {} - hProperties['id'] = text.toLowerCase().replace(/\s+/g, '-') - node.data['hProperties'] = hProperties - } - } - if (hasChildren(node)) { - for (const child of node.children) { - walk(child) - } - } - } - walk(tree) - return tree - } -} - -// Simple plugin to add heading IDs to markdown -export function rehypeHeadingIdsPlugin(): AstroIntegration { - return { - name: 'rehype-heading-ids', - hooks: { - 'astro:config:setup': ({ updateConfig }) => { - updateConfig({ - markdown: { - rehypePlugins: [rehypeHeadingIds], - }, - }) - }, - }, - } -} - -// Placeholder for unist-util-visit functionality -export function visit( - tree: AstNode, - type: string, - callback: (node: AstNode) => void, -) { - if (!hasChildren(tree)) return - - for (const child of tree.children) { - if (child.type === type) { - callback(child) - } - // Recursively visit children - if (hasChildren(child)) { - visit(child, type, callback) - } - } -} - -export default { - rehypeHeadingIdsPlugin, - visit, -} diff --git a/apps/web/src/plugins/remark-directive-sugar.ts b/apps/web/src/plugins/remark-directive-sugar.ts deleted file mode 100644 index 96f1f5df93..0000000000 --- a/apps/web/src/plugins/remark-directive-sugar.ts +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Remark plugin for directive sugar processing - */ - -// Simple type definitions for mdast -interface Root { - type: 'root' - children: Node[] -} - -interface Node { - type: string - children?: Node[] - value?: string - name?: string - data?: { - hName?: string - hProperties?: Record - } -} - -interface DirectiveNode extends Node { - name: string - attributes?: Record -} - -const isDirectiveNode = (node: Node): node is DirectiveNode => - (node.type === 'textDirective' || - node.type === 'leafDirective' || - node.type === 'containerDirective') && - typeof node.name === 'string' - -// Simple visit function implementation - local version -function visit( - tree: Node, - test: string | ((node: Node) => boolean), - callback: (node: Node) => void, -) { - const testFn = - typeof test === 'string' ? (node: Node) => node.type === test : test - - function walk(node: Node) { - if (testFn(node)) { - callback(node) - } - if (node.children) { - node.children.forEach(walk) - } - } - - walk(tree) -} - -export function remarkDirectiveSugar() { - return (tree: Root) => { - visit( - tree, - () => true, - (node: Node) => { - // Process directive nodes - if (isDirectiveNode(node)) { - // Handle different directive types - switch (node.name) { - case 'note': - // Transform note directives - if (node.children) { - node.type = 'paragraph' - node.data = { - hName: 'div', - hProperties: { - className: ['note', 'directive-note'], - }, - } - } - break - - case 'warning': - // Transform warning directives - if (node.children) { - node.type = 'paragraph' - node.data = { - hName: 'div', - hProperties: { - className: ['warning', 'directive-warning'], - }, - } - } - break - - case 'tip': - // Transform tip directives - if (node.children) { - node.type = 'paragraph' - node.data = { - hName: 'div', - hProperties: { - className: ['tip', 'directive-tip'], - }, - } - } - break - } - } - }, - ) - } -} - -export default remarkDirectiveSugar diff --git a/apps/web/src/plugins/remark-generate-og-image.ts b/apps/web/src/plugins/remark-generate-og-image.ts deleted file mode 100644 index 566159dbf7..0000000000 --- a/apps/web/src/plugins/remark-generate-og-image.ts +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Remark plugin for generating OpenGraph images - */ - -// Simple type definitions for mdast -interface Root { - type: 'root' - children: Node[] -} - -interface Node { - type: string - children?: Node[] - value?: string - depth?: number -} - -// Simple chalk implementation for logging -const chalk = { - blue: (text: string) => text, - green: (text: string) => text, - yellow: (text: string) => text, - red: (text: string) => text, - bold: (text: string) => text, -} - -export function remarkGenerateOgImage() { - return (tree: Root, file: any) => { - // Simple implementation - just log the processing - - // Add metadata for OG image generation - if (file?.data) { - file.data.ogImage = { - title: extractTitle(tree), - description: extractDescription(tree), - } - } - - return tree - } -} - -function extractTitle(tree: Root): string { - // Extract title from heading - let title = 'Default Title' - - function walk(node: any) { - if (node.type === 'heading' && node.depth === 1) { - if (node.children?.[0]?.value) { - title = node.children[0].value - } - } - if (node.children) { - node.children.forEach(walk) - } - } - - walk(tree) - return title -} - -function extractDescription(tree: Root): string { - // Extract first paragraph as description - let description = 'Default description' - let foundFirstParagraph = false - - function walk(node: any) { - if (node.type === 'paragraph' && !foundFirstParagraph) { - if (node.children?.[0]?.value) { - description = node.children[0].value.substring(0, 160) - foundFirstParagraph = true - } - } - if (node.children) { - node.children.forEach(walk) - } - } - - walk(tree) - return description -} - -export default remarkGenerateOgImage diff --git a/apps/web/src/plugins/remark-image-container.ts b/apps/web/src/plugins/remark-image-container.ts deleted file mode 100644 index 05c72da4cb..0000000000 --- a/apps/web/src/plugins/remark-image-container.ts +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Remark plugin for image container processing - */ - -// Simple type definitions for mdast -interface Root { - type: 'root' - children: Node[] -} - -// interface Paragraph { -// type: 'paragraph' -// children: PhrasingContent[] -// } - -// interface PhrasingContent { -// type: string -// url?: string -// alt?: string -// value?: string -// children?: Node[] -// } - -// Simple type definitions for mdast -interface Node { - type: string - children?: Node[] - value?: string - url?: string - alt?: string - data?: any -} - -// interface ImageNode extends Node { -// type: 'image' -// url: string -// alt?: string -// } - -interface ParagraphNode extends Node { - type: 'paragraph' - children: Node[] -} - -// Simple visit function implementation - local version -function visit( - tree: Node, - test: string | ((node: Node) => boolean), - callback: (node: Node) => void, -) { - const testFn = - typeof test === 'string' ? (node: Node) => node.type === test : test - - function walk(node: Node) { - if (testFn(node)) { - callback(node) - } - if (node.children) { - node.children.forEach(walk) - } - } - - walk(tree) -} - -export function remarkImageContainer() { - return (tree: Root) => { - visit(tree, 'paragraph', (node: any) => { - const paragraph = node as ParagraphNode - - // Check if paragraph contains only images - if (paragraph.children && paragraph.children.length > 0) { - const hasOnlyImages = paragraph.children.every( - (child: any) => child.type === 'image', - ) - - if (hasOnlyImages) { - // Transform paragraph to image container - paragraph.data = { - hName: 'div', - hProperties: { - className: ['image-container'], - }, - } - } - } - }) - } -} - -export default remarkImageContainer diff --git a/apps/web/src/plugins/remark-reading-time.ts b/apps/web/src/plugins/remark-reading-time.ts deleted file mode 100644 index 1eb9988fda..0000000000 --- a/apps/web/src/plugins/remark-reading-time.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Remark plugin for calculating reading time - */ - -// Simple type definitions for mdast -interface Root { - type: 'root' - children: Node[] -} - -interface Node { - type: string - children?: Node[] - value?: string -} - -// Simple implementation for reading time calculation -export function remarkReadingTime() { - return (tree: Root, file: any) => { - // Calculate reading time based on word count - const textContent = extractText(tree) - const wordCount = textContent - .split(/\s+/) - .filter((word) => word.length > 0).length - const readingTime = Math.ceil(wordCount / 200) // Average reading speed: 200 words per minute - - // Store reading time in file data for later use - if (file?.data) { - file.data.readingTime = readingTime - file.data.wordCount = wordCount - } - - return tree - } -} - -function extractText(tree: Root): string { - let text = '' - - function walk(node: any) { - if (node.type === 'text' && node.value) { - text += node.value + ' ' - } - if (node.children) { - node.children.forEach(walk) - } - } - - walk(tree) - return text.trim() -} - -export default remarkReadingTime diff --git a/apps/web/src/plugins/vite-plugin-external-node.js b/apps/web/src/plugins/vite-plugin-external-node.js deleted file mode 100644 index 65826f3359..0000000000 --- a/apps/web/src/plugins/vite-plugin-external-node.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Vite plugin to mark Node.js modules as external dependencies - */ -export default function externalNodePlugin() { - const nodeBuiltins = [ - 'fs', - 'fs/promises', - 'path', - 'os', - 'http', - 'https', - 'util', - 'crypto', - 'child_process', - 'stream', - 'events', - 'buffer', - 'process', - 'net', - 'tls', - 'zlib', - 'worker_threads', - 'diagnostics_channel', - 'inspector', - 'readline', - 'async_hooks', - 'node:fs', - 'node:fs/promises', - 'node:path', - 'node:os', - 'node:http', - 'node:https', - 'node:util', - 'node:crypto', - 'node:child_process', - 'node:stream', - 'node:events', - 'node:buffer', - 'node:process', - 'node:net', - 'node:tls', - 'node:zlib', - 'node:worker_threads', - 'node:diagnostics_channel', - 'node:inspector', - 'node:readline', - 'node:async_hooks', - ] - - return { - name: 'vite-plugin-external-node', - config(config) { - // Mark Node.js built-ins as external for SSR builds - config.build = config.build ?? {} - config.build.rollupOptions = config.build.rollupOptions ?? {} - - const existingExternal = config.build.rollupOptions.external ?? [] - const externalFn = - typeof existingExternal === 'function' - ? existingExternal - : (id) => - Array.isArray(existingExternal) - ? existingExternal.includes(id) - : existingExternal === id - - config.build.rollupOptions.external = (id) => { - return nodeBuiltins.includes(id) || externalFn(id) - } - }, - } -} -;(function () { - try { - var e = - 'undefined' != typeof window - ? window - : 'undefined' != typeof global - ? global - : 'undefined' != typeof globalThis - ? globalThis - : 'undefined' != typeof self - ? self - : {}, - n = new e.Error().stack - n && - ((e._sentryDebugIds = e._sentryDebugIds ?? {}), - (e._sentryDebugIds[n] = '997a2ae6-b7d4-509e-9ed0-412733abc2ae')) - } catch (error) { - // Intentionally empty - silencing Sentry debug errors - } -})() -//# debugId=997a2ae6-b7d4-509e-9ed0-412733abc2ae diff --git a/apps/web/src/plugins/vite-plugin-middleware-patch.js b/apps/web/src/plugins/vite-plugin-middleware-patch.js deleted file mode 100644 index 47538db5ba..0000000000 --- a/apps/web/src/plugins/vite-plugin-middleware-patch.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Vite plugin to fix circular dependency issues with Astro middleware - * This resolves the warning about sequence export causing circular dependencies - */ -export default function middlewarePatchPlugin() { - return { - name: 'vite-plugin-middleware-patch', - enforce: 'pre', - resolveId(id) { - // Intercept imports to astro:middleware and astro-internal:middleware - if (id === 'astro:middleware' || id === 'astro-internal:middleware') { - return 'virtual:patched-middleware' - } - return null - }, - load(id) { - if (id === 'virtual:patched-middleware') { - // Provide a direct export of sequence to avoid circular dependencies - return ` - // Direct import from sequence module to avoid circular dependencies - import { sequence as _sequence } from 'astro/dist/core/middleware/sequence.js'; - - // Re-export the sequence function - export const sequence = _sequence; - - // Export other middleware-related functions if needed - export * from 'astro/dist/core/middleware/app.js'; - export * from 'astro/dist/core/middleware/createContext.js'; - export * from 'astro/dist/core/middleware/createMiddleware.js'; - ` - } - return null - }, - } -} diff --git a/apps/web/src/plugins/vite-plugin-node-exclude.js b/apps/web/src/plugins/vite-plugin-node-exclude.js deleted file mode 100644 index f176357183..0000000000 --- a/apps/web/src/plugins/vite-plugin-node-exclude.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Vite plugin to exclude Node.js specific modules from browser builds - */ -export default function nodeExcludePlugin() { - const nodeModules = [ - 'fs', - 'path', - 'os', - 'crypto', - 'http', - 'https', - 'stream', - 'util', - 'events', - 'buffer', - 'process', - 'child_process', - 'net', - 'tls', - 'node:fs', - 'node:path', - 'node:os', - 'node:crypto', - 'node:http', - 'node:https', - 'node:stream', - 'node:util', - 'node:events', - 'node:buffer', - 'node:process', - 'node:child_process', - 'node:net', - 'node:tls', - ] - - return { - name: 'vite-plugin-node-exclude', - resolveId(id) { - // Exclude Node.js modules from browser builds - if (nodeModules.includes(id)) { - return { id, external: true } - } - return null - }, - } -} diff --git a/apps/web/src/plugins/vite-plugin-node-polyfill.js b/apps/web/src/plugins/vite-plugin-node-polyfill.js deleted file mode 100644 index 1be95eac47..0000000000 --- a/apps/web/src/plugins/vite-plugin-node-polyfill.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Vite plugin to provide Node.js polyfills for browser environment - */ -export default function nodePolyfillPlugin() { - return { - name: 'vite-plugin-node-polyfill', - config(config) { - // Add Node.js polyfills for browser builds - config.define = config.define ?? {} - config.define.global = 'globalThis' - config.define.process = 'process' - }, - configResolved(resolvedConfig) { - // Ensure polyfills are available in browser context - if (resolvedConfig.command === 'build' && !resolvedConfig.build.ssr) { - resolvedConfig.define = resolvedConfig.define ?? {} - resolvedConfig.define.global = 'globalThis' - } - }, - } -} diff --git a/apps/web/src/plugins/vite-plugin-rewrite-logger-import.js b/apps/web/src/plugins/vite-plugin-rewrite-logger-import.js deleted file mode 100644 index 0071832fe4..0000000000 --- a/apps/web/src/plugins/vite-plugin-rewrite-logger-import.js +++ /dev/null @@ -1,58 +0,0 @@ -import path from 'path' - -export default function rewriteLoggerImportPlugin() { - return { - name: 'rewrite-logger-import', - enforce: 'pre', - resolveId(source, _importer) { - try { - if (!source) { - return null - } - const relPattern = /^(?:\.\.\/)+lib\/logging\/build-safe-logger$/ - if (relPattern.test(source)) { - return path.resolve( - process.cwd(), - 'src/lib/logging/build-safe-logger.ts', - ) - } - return null - } catch { - return null - } - }, - transform(code, id) { - try { - if (!id || /node_modules/.test(id)) { - return null - } - if (!/(\.ts|\.tsx|\.js|\.jsx|\.mjs)$/.test(id)) { - return null - } - - const patternFrom = - /from\s+['"](?:\.\.\/)+lib\/logging\/build-safe-logger['"]/g - const patternDyn = - /import\(\s*['"](?:\.\.\/)+lib\/logging\/build-safe-logger['"]\s*\)/g - - let transformed = code - transformed = transformed.replace( - patternFrom, - "from '@/lib/logging/build-safe-logger'", - ) - transformed = transformed.replace( - patternDyn, - "import('@/lib/logging/build-safe-logger')", - ) - - if (transformed === code) { - return null - } - return { code: transformed, map: null } - } catch { - // Fail open: do not block the build on plugin transform errors - return null - } - }, - } -} diff --git a/apps/web/src/types.ts b/apps/web/src/types.ts index 55f83801f0..554aa38e84 100644 --- a/apps/web/src/types.ts +++ b/apps/web/src/types.ts @@ -543,8 +543,7 @@ export interface Ui { /** * Configures external links' behavior and appearance. * - * Used in `plugins/index.ts`, `src/components/base/Link.astro` - * and `src/layouts/BaseLayout.astro`. + * Used in `src/components/base/Link.astro` and `src/layouts/BaseLayout.astro`. */ externalLink: ExternalLink diff --git a/config/tsconfig.json b/config/tsconfig.json index ac2417a718..760473f153 100644 --- a/config/tsconfig.json +++ b/config/tsconfig.json @@ -68,7 +68,6 @@ "./*.config.js", "./*.config.ts", "./api/**/*.ts", - "./plugins/**/*.ts", "./.astro-env.d.ts" ], "exclude": [ diff --git a/plugins/index.ts b/plugins/index.ts deleted file mode 100644 index 25f42dabdd..0000000000 --- a/plugins/index.ts +++ /dev/null @@ -1,107 +0,0 @@ -// Type definitions for plugin arrays -type RemarkPlugin = (...args: unknown[]) => unknown -type RehypePlugin = (...args: unknown[]) => unknown -type RemarkPlugins = Array -type RehypePlugins = Array -import { rehypeHeadingIds } from '@astrojs/markdown-remark' -import rehypeCallouts from 'rehype-callouts' -import type { CreateProperties } from 'rehype-external-links' -import rehypeExternalLinks from 'rehype-external-links' -import remarkImgattr from 'remark-imgattr' -import { visit } from 'unist-util-visit' - -import { UI } from '../apps/web/src/config' -import remarkReadingTime from './remark-reading-time' - -export const remarkPlugins: RemarkPlugins = [ - // https://github.com/OliverSpeir/remark-imgattr - remarkImgattr, - remarkReadingTime, -] - -export const rehypePlugins: RehypePlugins = [ - // https://docs.astro.build/en/guides/markdown-content/#heading-ids-and-plugins - rehypeHeadingIds, - // https://github.com/lin-stephanie/rehype-callouts - [ - rehypeCallouts, - { - theme: 'vitepress', - }, - ], - // https://github.com/rehypejs/rehype-external-links - [ - rehypeExternalLinks, - { - rel: UI.externalLink.newTab ? 'noopener noreferrer' : [], - content: (el: Parameters[0]) => { - if (!UI.externalLink.newTab || !UI.externalLink.showNewTabIcon) { - return null - } - - let hasImage = false - visit(el, 'element', (childNode) => { - if (childNode.tagName === 'img') { - hasImage = true - return false - } - return undefined - }) - if (hasImage) { - return null - } - - return { - type: 'text', - value: '', - } - }, - contentProperties: (el: Parameters[0]) => { - if (!UI.externalLink.newTab || !UI.externalLink.showNewTabIcon) { - return null - } - - let hasImage = false - visit(el, 'element', (childNode) => { - if (childNode.tagName === 'img') { - hasImage = true - return false - } - return undefined - }) - if (hasImage) { - return null - } - - return { - 'u-i-lucide-external-link': true, - 'className': ['new-tab-icon'], - 'aria-hidden': 'true', - } - }, - properties: (el: Parameters[0]) => { - const props: Record = {} - const href = el.properties?.['href'] - - if (!href || typeof href !== 'string') { - return props - } - - if (UI.externalLink.newTab) { - props['target'] = '_blank' - props['ariaLabel'] = 'Open in new tab' - if ( - UI.externalLink.cursorType.length > 0 && - UI.externalLink.cursorType !== 'pointer' - ) { - props['className'] = Array.isArray(el.properties?.['className']) - ? [...el.properties['className'], 'external-link-cursor'] - : ['external-link-cursor'] - } - } - - return props - }, - }, - ], -] diff --git a/plugins/og-template/base64.ts b/plugins/og-template/base64.ts deleted file mode 100644 index 4a32ed604e..0000000000 --- a/plugins/og-template/base64.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { BgType } from '../../apps/web/src/types' - -type BackgroundBase64 = Partial> - -const backgroundBase64: BackgroundBase64 = { - plum: '/images/backgrounds/plum.png', - dot: '/images/backgrounds/dot.png', - rose: '/images/backgrounds/rose.png', - particle: '/images/backgrounds/particle.png', -} as const - -export default backgroundBase64 diff --git a/plugins/og-template/markup.ts b/plugins/og-template/markup.ts deleted file mode 100644 index 8e47941b41..0000000000 --- a/plugins/og-template/markup.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { html } from 'satori-html' - -import type { BgType } from '../../apps/web/src/types' -import backgroundBase64 from './base64' - -export function ogImageMarkup( - authorOrBrand: string, - title: string, - bgType: BgType, -) { - if (!['plum', 'dot', 'rose', 'particle'].includes(bgType)) { - throw new Error( - "The value of 'bgType' must be one of the following: 'plum', 'dot', 'rose', 'particle'.", - ) - } - - return html`
- open graph - -
-
- - - - - - - - - - -
- -
-
${authorOrBrand}
-
${title}
-
-
-
` -} diff --git a/plugins/remark-generate-og-image.ts b/plugins/remark-generate-og-image.ts deleted file mode 100644 index 173010ac43..0000000000 --- a/plugins/remark-generate-og-image.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { readFileSync, writeFileSync } from 'node:fs' -import { mkdir } from 'node:fs/promises' -import { basename, dirname } from 'node:path' - -import chalk from 'chalk' -import type { ReactNode } from 'react' -import type { SatoriOptions } from 'satori' -import satori from 'satori' -import type { VFile } from 'vfile' - -import { FEATURES } from '../apps/web/src/config' -import type { BgType } from '../apps/web/src/types' -import { - checkFileExistsInDir, - unescapeHTML, - type VNode, -} from '../apps/web/src/utils/common' -import { getCurrentFormattedTime } from '../apps/web/src/utils/datetime' -import { ogImageMarkup } from './og-template/markup' - -interface AstroFrontmatter { - draft?: boolean - redirect?: string - title?: string - ogImage?: boolean | string - bgType?: BgType -} - -interface AstroData { - astro: { - frontmatter: AstroFrontmatter - } -} - -const Inter = readFileSync('plugins/og-template/Inter-Regular-24pt.ttf') - -const satoriOptions: SatoriOptions = { - // debug: true, - width: 1200, - height: 630, - fonts: [ - { - name: 'Inter', - weight: 400, - style: 'normal', - data: Inter, - }, - ], -} - -async function generateOgImage( - authorOrBrand: string, - title: string, - bgType: BgType, - output: string, -) { - await mkdir(dirname(output), { recursive: true }) - - console.log( - `${chalk.black(getCurrentFormattedTime())} ${chalk.green(`Generating ${output}...`)}`, - ) - - try { - const node = ogImageMarkup(authorOrBrand, title, bgType) as VNode - const unescapedNode = unescapeHTML(node) as ReactNode - const svg = await satori(unescapedNode, satoriOptions) - - const compressedPngBuffer = Buffer.from(svg) - - writeFileSync(output, compressedPngBuffer) - } catch (e) { - console.error( - `${chalk.black(getCurrentFormattedTime())} ${chalk.red(`[ERROR] Failed to generate og image for '${basename(output)}.'`)}`, - ) - console.error(e) - } -} /** - * Used to generate {@link https://ogp.me/ Open Graph} images. - * - * @see https://github.com/vfile/vfile - */ -function remarkGenerateOgImage() { - const { ogImage } = FEATURES - - if (!(Array.isArray(ogImage) && ogImage[0])) { - return - } - - const { authorOrBrand, fallbackTitle, fallbackBgType } = ogImage[1] - - return async function processFile(file: VFile & { data: AstroData }) { - // regenerate fallback - const fallbackExists = await checkFileExistsInDir( - 'apps/web/public/og-images', - 'og-image.png', - ) - if (!fallbackExists) { - await generateOgImage( - authorOrBrand, - fallbackTitle, - fallbackBgType, - 'apps/web/public/og-images/og-image.png', - ) - } - - // check filename - const { basename: filename, extname, dirname: dirpath } = file - if (!filename || !(filename.endsWith('.md') || filename.endsWith('.mdx'))) { - return - } - - // check draft & redirect - const { - draft, - redirect, - title, - ogImage: pageOgImage, - bgType: pageBgType, - } = file.data.astro.frontmatter - if (draft || redirect) { - return - } - - // check if it need to be skipped - if (!title?.trim().length) { - return - } - if (pageOgImage === false) { - return - } - - // check if it has been generated - let nameWithoutExt = basename(filename, extname) - if (nameWithoutExt === 'index' && dirpath) { - nameWithoutExt = basename(dirpath) - } - - const existingImage = await checkFileExistsInDir( - 'apps/web/public/og-images', - `${nameWithoutExt}.png`, - ) - if (existingImage) { - return - } - - // check if it has been assigned & actually exists - if (pageOgImage && pageOgImage !== true) { - const assignedImageExists = await checkFileExistsInDir( - 'apps/web/public/og-images', - basename(pageOgImage), - ) - if (assignedImageExists) { - return - } - - console.warn( - `${chalk.black(getCurrentFormattedTime())} ${chalk.yellow(`[WARN] The '${pageOgImage}' specified in '${file.path}' was not found.`)}\n ${chalk.bold('Hint:')} See ${chalk.cyan.underline('https://astro-antfustyle-theme.vercel.app/blog/about-open-graph-images/#configuring-og-images')} for more information on og image.`, - ) - return - } - - // get bgType - const bgType = pageBgType ?? fallbackBgType - - // generate og images - await generateOgImage( - authorOrBrand, - title.trim(), - bgType, - `apps/web/public/og-images/${nameWithoutExt}.png`, - ) - } -} - -export default remarkGenerateOgImage diff --git a/plugins/remark-reading-time.ts b/plugins/remark-reading-time.ts deleted file mode 100644 index ee2543642a..0000000000 --- a/plugins/remark-reading-time.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { Root } from 'mdast' -import { toString } from 'mdast-util-to-string' -import getReadingTime from 'reading-time' -import type { VFile } from 'vfile' - -/** - * Used to add a reading time property to the frontmatter of your Markdown or MDX files. - * - * @see https://docs.astro.build/en/recipes/reading-time/ - */ -function remarkReadingTime() { - // - return (tree: Root, file: VFile) => { - const frontmatter = (file.data as any).astro?.frontmatter - if ( - !frontmatter || - frontmatter['minutesRead'] || - frontmatter['minutesRead'] === 0 - ) { - return - } - - const textOnPage = toString(tree) - const readingTime = getReadingTime(textOnPage) - - frontmatter['minutesRead'] = Math.max(1, Math.round(readingTime.minutes)) - } -} - -export default remarkReadingTime diff --git a/tsconfig.json b/tsconfig.json index 58501a460c..76677762a4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -69,7 +69,6 @@ "./*.config.mts", "./vitest.setup.ts", "./api/**/*.ts", - "./plugins/**/*.ts", "./packages/memory-schema/src/**/*.ts", "./.astro-env.d.ts", "./apps/web/src/types/declarations.d.ts",