feat: ship blog platform admin and deploy stack
This commit is contained in:
@@ -9,7 +9,15 @@ export type ParsedMarkdownMeta = {
|
||||
image: string
|
||||
images: string[]
|
||||
pinned: boolean
|
||||
published: boolean
|
||||
status: string
|
||||
visibility: string
|
||||
publishAt: string
|
||||
unpublishAt: string
|
||||
canonicalUrl: string
|
||||
noindex: boolean
|
||||
ogImage: string
|
||||
redirectFrom: string[]
|
||||
redirectTo: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
@@ -28,7 +36,15 @@ const defaultMeta: ParsedMarkdownMeta = {
|
||||
image: '',
|
||||
images: [],
|
||||
pinned: false,
|
||||
published: true,
|
||||
status: 'published',
|
||||
visibility: 'public',
|
||||
publishAt: '',
|
||||
unpublishAt: '',
|
||||
canonicalUrl: '',
|
||||
noindex: false,
|
||||
ogImage: '',
|
||||
redirectFrom: [],
|
||||
redirectTo: '',
|
||||
tags: [],
|
||||
}
|
||||
|
||||
@@ -102,7 +118,7 @@ export function parseMarkdownDocument(markdown: string): ParsedMarkdownDocument
|
||||
|
||||
const frontmatter = normalized.slice(4, endIndex)
|
||||
const body = normalized.slice(endIndex + 5).trimStart()
|
||||
let currentListKey: 'tags' | 'images' | 'categories' | null = null
|
||||
let currentListKey: 'tags' | 'images' | 'categories' | 'redirect_from' | null = null
|
||||
const categories: string[] = []
|
||||
|
||||
frontmatter.split('\n').forEach((line) => {
|
||||
@@ -118,6 +134,8 @@ export function parseMarkdownDocument(markdown: string): ParsedMarkdownDocument
|
||||
meta.tags.push(nextValue)
|
||||
} else if (currentListKey === 'images') {
|
||||
meta.images.push(nextValue)
|
||||
} else if (currentListKey === 'redirect_from') {
|
||||
meta.redirectFrom.push(nextValue)
|
||||
} else {
|
||||
categories.push(nextValue)
|
||||
}
|
||||
@@ -155,6 +173,16 @@ export function parseMarkdownDocument(markdown: string): ParsedMarkdownDocument
|
||||
return
|
||||
}
|
||||
|
||||
if (key === 'redirect_from') {
|
||||
const redirectFrom = toStringList(value)
|
||||
if (redirectFrom.length) {
|
||||
meta.redirectFrom = redirectFrom
|
||||
} else if (!String(rawValue).trim()) {
|
||||
currentListKey = 'redirect_from'
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (key === 'categories' || key === 'category') {
|
||||
const parsedCategories = toStringList(value)
|
||||
if (parsedCategories.length) {
|
||||
@@ -184,12 +212,36 @@ export function parseMarkdownDocument(markdown: string): ParsedMarkdownDocument
|
||||
case 'pinned':
|
||||
meta.pinned = Boolean(value)
|
||||
break
|
||||
case 'status':
|
||||
meta.status = String(value).trim() || 'published'
|
||||
break
|
||||
case 'visibility':
|
||||
meta.visibility = String(value).trim() || 'public'
|
||||
break
|
||||
case 'publish_at':
|
||||
meta.publishAt = String(value).trim()
|
||||
break
|
||||
case 'unpublish_at':
|
||||
meta.unpublishAt = String(value).trim()
|
||||
break
|
||||
case 'canonical_url':
|
||||
meta.canonicalUrl = String(value).trim()
|
||||
break
|
||||
case 'noindex':
|
||||
meta.noindex = Boolean(value)
|
||||
break
|
||||
case 'og_image':
|
||||
meta.ogImage = String(value).trim()
|
||||
break
|
||||
case 'redirect_to':
|
||||
meta.redirectTo = String(value).trim()
|
||||
break
|
||||
case 'published':
|
||||
meta.published = value !== false
|
||||
meta.status = value === false ? 'draft' : 'published'
|
||||
break
|
||||
case 'draft':
|
||||
if (value === true) {
|
||||
meta.published = false
|
||||
meta.status = 'draft'
|
||||
}
|
||||
break
|
||||
default:
|
||||
@@ -223,7 +275,17 @@ export function buildMarkdownDocument(meta: ParsedMarkdownMeta, body: string) {
|
||||
|
||||
lines.push(`post_type: ${JSON.stringify(meta.postType.trim() || 'article')}`)
|
||||
lines.push(`pinned: ${meta.pinned ? 'true' : 'false'}`)
|
||||
lines.push(`published: ${meta.published ? 'true' : 'false'}`)
|
||||
lines.push(`status: ${JSON.stringify(meta.status.trim() || 'published')}`)
|
||||
lines.push(`visibility: ${JSON.stringify(meta.visibility.trim() || 'public')}`)
|
||||
lines.push(`noindex: ${meta.noindex ? 'true' : 'false'}`)
|
||||
|
||||
if (meta.publishAt.trim()) {
|
||||
lines.push(`publish_at: ${JSON.stringify(meta.publishAt.trim())}`)
|
||||
}
|
||||
|
||||
if (meta.unpublishAt.trim()) {
|
||||
lines.push(`unpublish_at: ${JSON.stringify(meta.unpublishAt.trim())}`)
|
||||
}
|
||||
|
||||
if (meta.image.trim()) {
|
||||
lines.push(`image: ${JSON.stringify(meta.image.trim())}`)
|
||||
@@ -243,5 +305,24 @@ export function buildMarkdownDocument(meta: ParsedMarkdownMeta, body: string) {
|
||||
})
|
||||
}
|
||||
|
||||
if (meta.canonicalUrl.trim()) {
|
||||
lines.push(`canonical_url: ${JSON.stringify(meta.canonicalUrl.trim())}`)
|
||||
}
|
||||
|
||||
if (meta.ogImage.trim()) {
|
||||
lines.push(`og_image: ${JSON.stringify(meta.ogImage.trim())}`)
|
||||
}
|
||||
|
||||
if (meta.redirectFrom.length) {
|
||||
lines.push('redirect_from:')
|
||||
meta.redirectFrom.forEach((item) => {
|
||||
lines.push(` - ${JSON.stringify(item)}`)
|
||||
})
|
||||
}
|
||||
|
||||
if (meta.redirectTo.trim()) {
|
||||
lines.push(`redirect_to: ${JSON.stringify(meta.redirectTo.trim())}`)
|
||||
}
|
||||
|
||||
return `${lines.join('\n')}\n---\n\n${body.trim()}\n`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user