1
0
mirror of https://github.com/kremalicious/astro-redirect-from.git synced 2024-11-24 19:10:23 +01:00
This commit is contained in:
Matthias Kretschmann 2023-09-23 14:17:33 +01:00
parent 659c0a0fc9
commit 93e72936e4
Signed by: m
GPG Key ID: 606EEEF3C479A91F
7 changed files with 94 additions and 59 deletions

13
package-lock.json generated
View File

@ -9,8 +9,8 @@
"version": "0.1.0",
"license": "MIT",
"dependencies": {
"astro": "^3.1.2",
"fast-glob": "^3.3.1",
"astro": ">= 3",
"globby": "^13.2.2",
"gray-matter": "^4.0.3"
},
"devDependencies": {
@ -25,6 +25,10 @@
"typescript": "^5.2.2",
"vite": "^4.4.9"
},
"engines": {
"node": ">=18.14.1",
"npm": ">=6.14.0"
},
"peerDependencies": {
"astro": ">= 3"
}
@ -3101,7 +3105,6 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"dev": true,
"dependencies": {
"path-type": "^4.0.0"
},
@ -4123,7 +4126,6 @@
"version": "13.2.2",
"resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz",
"integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==",
"dev": true,
"dependencies": {
"dir-glob": "^3.0.1",
"fast-glob": "^3.3.0",
@ -4571,7 +4573,6 @@
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true,
"engines": {
"node": ">= 4"
}
@ -7523,7 +7524,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -9024,7 +9024,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
"integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
"dev": true,
"engines": {
"node": ">=12"
},

View File

@ -18,6 +18,12 @@
"release": "release-it --non-interactive",
"prepublishOnly": "npm run build"
},
"exports": {
".": "./dist/index.js"
},
"files": [
"dist"
],
"devDependencies": {
"@types/node": "^20.6.3",
"@typescript-eslint/eslint-plugin": "^6.7.2",
@ -32,7 +38,7 @@
},
"dependencies": {
"astro": ">= 3",
"fast-glob": "^3.3.1",
"globby": "^13.2.2",
"gray-matter": "^4.0.3"
},
"peerDependencies": {

32
src/getRedirects.ts Normal file
View File

@ -0,0 +1,32 @@
import path from 'node:path'
import type { Redirects } from './types'
import { getMarkdownFrontmatter } from './utils'
export async function getRedirects(
files: string[],
srcDir: string,
getSlug: (filePath: string) => string
) {
const redirects: Redirects = {}
for (const file of files) {
const frontmatter = await getMarkdownFrontmatter(path.join(srcDir, file))
const redirectFrom: string[] = frontmatter?.redirect_from
if (
!frontmatter ||
!redirectFrom ||
(import.meta.env.PROD && frontmatter.draft === true)
)
continue
let postSlug = frontmatter.slug
if (!postSlug) postSlug = getSlug(file)
if (!postSlug) continue
for (const slug of redirectFrom) {
redirects[slug] = postSlug
}
}
return redirects
}

View File

@ -1,73 +1,43 @@
import fs from 'node:fs/promises'
import path from 'node:path'
import fg from 'fast-glob'
import matter from 'gray-matter'
import type { AstroIntegration, AstroIntegrationLogger } from 'astro'
import { getSlugFromFilePath, writeJson } from './utils'
type PluginOptions = {
contentDir?: string
getSlug?: (filePath: string) => string
}
import type { AstroIntegration } from 'astro'
import type { PluginOptions } from './types'
import { getMarkdownFiles, getSlugFromFilePath, writeJson } from './utils'
import { getRedirects } from './getRedirects'
export default function astroRedirectFrom({
contentDir = 'src/pages/',
getSlug = getSlugFromFilePath
}: PluginOptions = {}): AstroIntegration {
const sourceDir = path.join(process.cwd(), contentDir)
}: PluginOptions): AstroIntegration {
const contentDirPath = path.join(process.cwd(), contentDir)
return {
name: 'redirect-from',
hooks: {
'astro:config:setup': async ({
updateConfig,
logger
}: {
updateConfig: (newConfig: Record<string, any>) => void
logger: AstroIntegrationLogger
}) => {
const redirects: { [old: string]: string } = {}
'astro:config:setup': async ({ config, updateConfig, logger }) => {
try {
const markdownFiles = await fg.glob('./**/*.{md,mdx}', {
cwd: sourceDir
})
const markdownFiles = await getMarkdownFiles(contentDirPath)
if (!markdownFiles?.length) {
logger.warn('No markdown files found')
return
}
for (const markdownFile of markdownFiles) {
const fileContent = await fs.readFile(
path.join(sourceDir, markdownFile),
'utf-8'
)
const { data: frontmatter } = matter(fileContent)
const postRedirectFrom: string[] = frontmatter?.redirect_from
if (
!frontmatter ||
!postRedirectFrom ||
// filter out drafts in production
(import.meta.env.PROD && frontmatter.draft === true)
)
continue
let postSlug = frontmatter.slug
if (!postSlug) postSlug = getSlug(markdownFile)
if (!postSlug) continue
for (const slug of postRedirectFrom) {
redirects[slug] = postSlug
}
const redirects = await getRedirects(
markdownFiles,
contentDirPath,
getSlug
)
if (!redirects || !Object.keys(redirects).length) {
logger.info('No redirects found in markdown files')
return
}
updateConfig({ redirects })
await writeJson(
path.join(process.cwd(), '.astro', 'redirect_from.json'),
redirects
const redirectFilePath = path.join(
config.cacheDir.pathname, // Default is ./node_modules/.astro/
'redirect_from.json'
)
await writeJson(redirectFilePath, redirects)
logger.info(
`Added ${Object.keys(redirects).length} redirects to Astro config`

8
src/types.ts Normal file
View File

@ -0,0 +1,8 @@
export type GetSlug = (filePath: string) => string
export type PluginOptions = {
contentDir?: string
getSlug?: GetSlug
}
export type Redirects = { [old: string]: string }

View File

@ -1,5 +1,21 @@
import path from 'node:path'
import { promises as fs, type PathLike } from 'node:fs'
import { globby } from 'globby'
import matter from 'gray-matter'
export async function getMarkdownFiles(sourceDir: string) {
const markdownFiles = await globby('./**/*.{md,mdx}', {
cwd: sourceDir,
gitignore: true
})
return markdownFiles
}
export async function getMarkdownFrontmatter(filePath: string) {
const fileContent = await fs.readFile(filePath, { encoding: 'utf-8' })
const { data: frontmatter } = matter(fileContent)
return frontmatter
}
export function getSlugFromFilePath(filePath: string) {
const parsedPath = path.parse(filePath)

View File

@ -4,6 +4,10 @@
"exclude": ["node_modules", "dist"],
"compilerOptions": {
"outDir": "./dist",
"types": ["vite/client"]
"types": ["vite/client"],
"declaration": true,
// ovewrite astro/tsconfigs values
"noEmit": false,
"allowImportingTsExtensions": false
}
}