feat(06-01): add Nitro hook content:file:afterParse for reading-time injection
- Register `content:file:afterParse` hook to inject `wordCount` + `minutes` on every parsed markdown content object (D-19: 200 wpm, floor 1 min). - Import pure util `countWordsInMinimalBody` from app/utils/countWords. - Guard against non-`.md` files (defensive — hook fires on all sources). - Values persist in @nuxt/content SQLite DB and are queryable via queryCollection thanks to matching Zod fields (content.config.ts).
This commit is contained in:
+3
-3
@@ -3,8 +3,8 @@ gsd_state_version: 1.0
|
|||||||
milestone: v1.0
|
milestone: v1.0
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
status: Context gathered — ready for /gsd-plan-phase 6
|
status: Context gathered — ready for /gsd-plan-phase 6
|
||||||
last_updated: "2026-04-21T23:11:57.514Z"
|
last_updated: "2026-04-22T06:55:05.535Z"
|
||||||
last_activity: 2026-04-21
|
last_activity: 2026-04-22
|
||||||
progress:
|
progress:
|
||||||
total_phases: 8
|
total_phases: 8
|
||||||
completed_phases: 3
|
completed_phases: 3
|
||||||
@@ -26,7 +26,7 @@ progress:
|
|||||||
Phase: Phase 6 — Blog Pages
|
Phase: Phase 6 — Blog Pages
|
||||||
Plan: —
|
Plan: —
|
||||||
Status: Context gathered — ready for /gsd-plan-phase 6
|
Status: Context gathered — ready for /gsd-plan-phase 6
|
||||||
Last activity: 2026-04-21
|
Last activity: 2026-04-22
|
||||||
Resume file: .planning/phases/06-blog-pages/06-UI-SPEC.md
|
Resume file: .planning/phases/06-blog-pages/06-UI-SPEC.md
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { countWordsInMinimalBody } from '~/utils/countWords'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nitro plugin: compute reading time for every markdown content file at parse time.
|
||||||
|
*
|
||||||
|
* Injects `wordCount` (number) and `minutes` (number, min 1) on the content object.
|
||||||
|
* Values are persisted in the @nuxt/content SQLite DB and queryable via queryCollection
|
||||||
|
* thanks to the matching Zod schema fields in content.config.ts (per D-18 + D-19).
|
||||||
|
*
|
||||||
|
* Hook reference: https://content.nuxt.com/docs/advanced/hooks
|
||||||
|
*/
|
||||||
|
export default defineNitroPlugin((nitroApp) => {
|
||||||
|
nitroApp.hooks.hook('content:file:afterParse', (ctx) => {
|
||||||
|
const { file, content } = ctx
|
||||||
|
|
||||||
|
// Only process markdown files (defensive — hook fires on all sources)
|
||||||
|
if (!file.id?.endsWith('.md')) return
|
||||||
|
|
||||||
|
const wordCount = countWordsInMinimalBody(content.body)
|
||||||
|
content.wordCount = wordCount
|
||||||
|
content.minutes = Math.max(1, Math.ceil(wordCount / 200)) // D-19: 200 wpm, floor 1 min
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user