feat: DEV-99 blog migration (#3870)

* feat: blog migration w/ fixes

Co-authored-by: Prospector <prospectordev@gmail.com>

* feat: add changelog button to news page

* fix: lint issues

* refactor: replace nuxt content with `@modrinth/blog`

* feat: shared public folder

* feat: try lazy loading html content

* feat: rss + hide newsletter btn + blog.config.ts

* feat: add new chapter modrinth servers post

* fix: lint issues

* fix: only generate RSS feed if changes detected

* fix: utils dep

* fix: lockfile dep

* feat: GET /email/subscribe + subscription button

* fix: lint issues

* feat: articles.json for app

* Made grid more responsive

* fix: changes

* Make margin slightly smaller in lists

* Fix footer link

* feat: latest news

* Fix responsiveness

* Remove old utm link

* Update changelog

* Lint

---------

Co-authored-by: Prospector <prospectordev@gmail.com>
This commit is contained in:
IMB11
2025-07-01 02:59:08 +01:00
committed by GitHub
parent fdb2b1195e
commit eef09e1ffe
220 changed files with 5094 additions and 681 deletions

40
packages/blog/utils.ts Normal file
View File

@@ -0,0 +1,40 @@
import { execSync } from 'child_process'
import * as path from 'path'
let REPO_ROOT_CACHE: string | null = null
export function getRepoRoot(): string {
if (REPO_ROOT_CACHE) return REPO_ROOT_CACHE
return (REPO_ROOT_CACHE = execSync('git rev-parse --show-toplevel').toString().trim())
}
export function repoPath(...segments: string[]): string {
return path.join(getRepoRoot(), ...segments)
}
export async function copyDir(
src: string,
dest: string,
logFn: (src: string, dest: string) => void = () => {},
): Promise<void> {
const { promises: fs } = await import('fs')
await fs.mkdir(dest, { recursive: true })
const entries = await fs.readdir(src, { withFileTypes: true })
for (const entry of entries) {
const srcPath = path.join(src, entry.name)
const destPath = path.join(dest, entry.name)
if (entry.isDirectory()) {
await copyDir(srcPath, destPath, logFn)
} else if (entry.isFile()) {
await fs.copyFile(srcPath, destPath)
logFn(srcPath, destPath)
}
}
}
export function toVarName(file: string): string {
return file
.replace(/\.md$/, '')
.replace(/[^a-zA-Z0-9]/g, '_')
.replace(/^_+/, '')
.replace(/_+$/, '')
}