Skip to content

Commit

Permalink
fix: πŸ› preamble, coverImage InnerDocument are loaded from asyncData #62
Browse files Browse the repository at this point in the history
  • Loading branch information
renoirb committed Oct 17, 2024
1 parent 939ea64 commit 40fd305
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 143 deletions.
92 changes: 31 additions & 61 deletions lib/model/content/front-matter-inner-document.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { strict as assert } from 'assert'
import { isObject } from '../../runtime'
import { abbreviatize } from '../abbreviations'
import type { contentFunc } from '@nuxt/content'
import { abbreviatize } from '../..'
import type {
INuxtContentParsedDocument,
VueNodeType,
VueRenderTree,
VueRenderTreeNonRoot,
VueNodeTag,
} from '../../types'
import type { INuxtContentDatabase } from './parser'
import type { INuxtContentResult } from './model'

export interface IFrontMatterInnerDocument {
/**
Expand Down Expand Up @@ -68,70 +66,59 @@ export interface IFrontMatterInnerDocumentParsed
document: INuxtContentParsedDocument | null
}

export const parseMarkdownText = async (
document: IFrontMatterInnerDocument,
database: INuxtContentDatabase,

export const createNuxtContentParsedDocument = async (
input: { text: string } | undefined,
$content: contentFunc,
): Promise<INuxtContentParsedDocument> => {
let body: INuxtContentParsedDocument
if (isObject(document) === false) {
const message = `Unexpected input, we expect an object`
throw new TypeError(message)
}
let errorSuffix = ''
if (isFrontMatterInnerDocument(document)) {
try {
/**
* Make all text with abbreviations to be wrapped into
* appropriate abbr tag.
*/
const textContent = abbreviatize(document.text)
/**
* Taking on what markdown.toJSON returns
* https://github.com/nuxt/content/blob/%40nuxt/content%401.10.0/packages/content/parsers/markdown/index.js#L95
*/
const parsed = await database.markdown.toJSON(textContent)
if (parsed && 'body' in parsed) {
body = parsed as INuxtContentParsedDocument
return body
}
} catch (e) {
errorSuffix += String(e)
}
let md = ''
if (input && Reflect.has(input, 'text')) {
md = input.text
}
const message = `There is no content to parse` + errorSuffix
throw new Error(message)
await Promise.resolve()
/**
* Make all text with abbreviations to be wrapped into
* appropriate abbr tag.
*/
md = abbreviatize(md)
/**
* Taking on what markdown.toJSON returns
* https://github.com/nuxt/content/blob/%40nuxt/content%401.10.0/packages/content/parsers/markdown/index.js#L95
*/
const out = await $content?.database?.markdown?.toJSON(md)
return out as INuxtContentParsedDocument
}

export const isFrontMatterInnerDocument = (
input: any,
input: unknown,
): input is IFrontMatterInnerDocument => {
let out: boolean = false
if (input && 'text' in input) {
if (input && Reflect.has(input, 'text')) {
out = true
}
return out
}

export const assertsFrontMatterInnerDocument = (
input: any,
): asserts input is IFrontMatterInnerDocument => {
export const assertsFrontMatterInnerDocument: (input: unknown) => asserts input is IFrontMatterInnerDocument = (
input,
) => {
const expectedMessage = `We expected to receive an IFrontMatterInnerDocument`
assert.equal(isFrontMatterInnerDocument(input), true, expectedMessage)
}

export const isFrontMatterCoverImageInnerDocument = (
input: any,
input: unknown,
): input is IFrontMatterCoverImageInnerDocument => {
let out: boolean = false
if (input && 'text' in input && 'src' in input) {
if (isFrontMatterInnerDocument(input) && Reflect.has(input, 'src')) {
out = true
}
return out
}

export const assertsFrontMatterCoverImageInnerDocument = (
input: any,
): asserts input is IFrontMatterCoverImageInnerDocument => {
export const assertsFrontMatterCoverImageInnerDocument: (input: unknown) => asserts input is IFrontMatterInnerDocument = (
input,
) => {
const expectedMessage = `We expected to receive an IFrontMatterCoverImageInnerDocument`
assert.equal(
isFrontMatterCoverImageInnerDocument(input),
Expand All @@ -140,23 +127,6 @@ export const assertsFrontMatterCoverImageInnerDocument = (
)
}

export const extractFrontMatterInnerDocument = (
input: INuxtContentResult,
key: string,
): IFrontMatterInnerDocument | null => {
let out: null | IFrontMatterInnerDocument = null
if (isObject(input) === false) {
const message = `Unexpected input, we expect an object`
throw new TypeError(message)
}
if (key in input) {
if (isFrontMatterInnerDocument(input[key])) {
out = input[key]
}
}
return out
}


export const getVueNodeTag = (node: VueRenderTreeNonRoot): VueNodeTag => {
if (getVueNodeType(node) === 'element' && 'tag' in node) {
Expand Down
75 changes: 27 additions & 48 deletions lib/runtime/nuxt-content.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import {
extractFrontMatterInnerDocument,
parseMarkdownText,
} from '../model/content'
import {
extractFrontMatterTagsAndNormalize,
isFrontMatterCoverImageInnerDocument,
isFrontMatterInnerDocument,
} from '../model'
import type {
IFrontMatterCoverImageInnerDocument,
IFrontMatterInnerDocument,
INuxtOptionsHooks,
} from '../model/content'
import { extractFrontMatterTagsAndNormalize } from '..'
import type { INuxtOptionsHooks } from '..'
import { extractVueTreeLinks } from './nuxt-content-links'

const allPages = new Map<string, Record<string, string | string[]>>()
Expand All @@ -32,8 +20,30 @@ export const getNuxtContentAllLinks = (): string[] => {
return allLinks
}

/**
* nuxt/content's
* - `'content:file:beforeParse ?`
* - `'content:file:beforeInsert': async (document, database) => {}`
* - `'content:options ?`
* - `'content:ready': ($content) => {}`
*
* Probably the best place to do AppVeryOldArticle
*
* Bookmarks:
* - https://content.nuxt.com/v1/getting-started/advanced#contentfilebeforeparse
*/
export const nuxtContentHooks: INuxtOptionsHooks = {
'content:file:beforeInsert': async (document, database) => {
'content:file:beforeInsert': async (document) => {
await Promise.resolve()
/**
* Reminder
* This is a hook that runs before the content is inserted
* for every page.
*
* What's also available here
*
* - `process.client`
*/
const {
description = '',
excerpt = '',
Expand All @@ -52,14 +62,15 @@ export const nuxtContentHooks: INuxtOptionsHooks = {
description,
excerpt,
}

if (!allPages.has(path) && redirect === '') {
allPages.set(path, item)
}

// Normalize tags from the source so we can have articles
// with same word, different CaSiNg (e.g. Foo and foo) as the same
const tags = extractFrontMatterTagsAndNormalize('tags', document)
Object.assign(document, { tags })
Reflect.set(document, 'tags', tags)
const categories = extractFrontMatterTagsAndNormalize(
'categories',
document,
Expand All @@ -76,37 +87,5 @@ export const nuxtContentHooks: INuxtOptionsHooks = {
if (links.length > 0) {
allLinks.push(...links)
}

// ------------------------------------------------------------------------
let preamble: IFrontMatterInnerDocument | null = null
const preambleMaybe = extractFrontMatterInnerDocument(document, 'preamble')
if (isFrontMatterInnerDocument(preambleMaybe)) {
const parsedDocument = await parseMarkdownText(preambleMaybe, database)

const merging = Object.assign(document.preamble, {
document: parsedDocument,
})
if (isFrontMatterInnerDocument(merging)) {
preamble = merging
}
}
Reflect.set(document, 'preamble', preamble)
// ------------------------------------------------------------------------
let coverImage: IFrontMatterCoverImageInnerDocument | null = null
const coverImageMaybe = extractFrontMatterInnerDocument(
document,
'coverImage',
)
if (isFrontMatterInnerDocument(coverImageMaybe)) {
const parsedDocument = await parseMarkdownText(coverImageMaybe, database)
const merging = Object.assign(document.coverImage, {
document: parsedDocument,
})
if (isFrontMatterCoverImageInnerDocument(merging)) {
coverImage = merging
}
}
Reflect.set(document, 'coverImage', coverImage)
// ------------------------------------------------------------------------
},
}
Loading

0 comments on commit 40fd305

Please sign in to comment.