| | import matter from '@gr2m/gray-matter' |
| |
|
| | import { validateJson } from '@/tests/lib/validate-json-schema' |
| |
|
| | interface ReadFrontmatterOptions { |
| | schema?: Record<string, any> |
| | filepath?: string | null |
| | } |
| |
|
| | function readFrontmatter(markdown: string, opts: ReadFrontmatterOptions = {}) { |
| | const schema = opts.schema || { type: 'object', properties: {} } |
| | const filepath = opts.filepath || null |
| |
|
| | let content |
| | let data |
| |
|
| | try { |
| | ;({ content, data } = matter(markdown)) |
| | } catch (e: any) { |
| | const defaultReason = 'invalid frontmatter entry' |
| |
|
| | const reason = e.reason |
| | ? |
| | e.reason.startsWith('can not read a block mapping entry;') || |
| | e.reason === 'bad indentation of a mapping entry' |
| | ? defaultReason |
| | : e.reason |
| | : defaultReason |
| |
|
| | const error: any = { |
| | reason, |
| | message: 'YML parsing error!', |
| | } |
| |
|
| | if (filepath) error.filepath = filepath |
| | const errors = [error] |
| | console.warn(errors) |
| |
|
| | return { errors } |
| | } |
| |
|
| | const validate: any = validateJson(schema, data) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const cleanPropertyPath = (params: Record<string, any>, instancePath: string) => { |
| | const mainProps = Object.values(params)[0] |
| | if (!instancePath) return mainProps |
| |
|
| | const prefixProps = instancePath.replace('/', '').replace(/\//g, '.') |
| | return typeof mainProps !== 'object' ? `${prefixProps}.${mainProps}` : prefixProps |
| | } |
| |
|
| | const errors = [] |
| |
|
| | if (!validate.isValid && filepath) { |
| | const formattedErrors = validate.errors.map((error: any) => { |
| | const userFriendly: any = {} |
| | userFriendly.property = cleanPropertyPath(error.params, error.instancePath) |
| | userFriendly.message = error.message |
| | userFriendly.reason = error.keyword |
| | userFriendly.filepath = filepath |
| | return userFriendly |
| | }) |
| | errors.push(...formattedErrors) |
| | } else if (!validate.isValid) { |
| | errors.push(...validate.errors) |
| | } |
| |
|
| | return { content, data, errors } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | readFrontmatter.stringify = matter.stringify |
| |
|
| | export default readFrontmatter |
| |
|