From f6e8100da143d522c90dc34fe0ae6c5107ad9c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=97=8D+85CD?= <50108258+kwaa@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:08:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(remark-fff):=20=E2=9C=A8=20support=20neste?= =?UTF-8?q?d=20target?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/poor-glasses-deliver.md | 9 +++ packages/remark-fff/src/plugin.ts | 64 ++++++++++++-------- packages/remark-fff/src/types.ts | 39 ++++-------- packages/remark-fff/test/frontmatter.spec.ts | 23 +++++++ 4 files changed, 83 insertions(+), 52 deletions(-) create mode 100644 .changeset/poor-glasses-deliver.md diff --git a/.changeset/poor-glasses-deliver.md b/.changeset/poor-glasses-deliver.md new file mode 100644 index 0000000..7bf142c --- /dev/null +++ b/.changeset/poor-glasses-deliver.md @@ -0,0 +1,9 @@ +--- +"remark-fff": patch +"fff-flavored-frontmatter": patch +"fff-transform-presets": patch +"indiekit-preset-fff": patch +"markdown-it-fff": patch +--- + +Version 1.2.0-alpha.1 diff --git a/packages/remark-fff/src/plugin.ts b/packages/remark-fff/src/plugin.ts index b5b2e09..80b12f0 100644 --- a/packages/remark-fff/src/plugin.ts +++ b/packages/remark-fff/src/plugin.ts @@ -2,7 +2,7 @@ import type { Plugin, Transformer } from 'unified' import { strict, transform } from 'fff-flavored-frontmatter' -import type { _Post, RemarkFFFOptions } from './types' +import type { RemarkFFFOptions } from './types' /** * Remark plugin for auto-conversion other frontmatter variable formats to {@link https://fff.js.org | FFF Flavored Frontmatter}. @@ -19,40 +19,52 @@ export const remarkFFF: Plugin<[RemarkFFFOptions]> }, ): Transformer => (_tree, file) => { - // make TS happy - const post: _Post = file as unknown as _Post - const fm = transform( - { - ...(options.target === 'mdsvex' - ? post.data.fm - : (options.target === 'astro' - ? post.data.astro.frontmatter - // eslint-disable-next-line unicorn/no-nested-ternary - : (options.target === 'nuxt' - ? post.data - : post.data))), - }, - [ - ...options.presets, - ...(options.strict ? [strict(options.strict)] : []), - ], - ) + let targets: string[] | undefined + + // Compatible with old target parameters before 1.2. + // TODO: remove in 1.3 switch (options.target) { case 'mdsvex': { - file.data.fm = fm + targets = ['fm'] break } case 'astro': { - file.data.astro = { - ...file.data.astro as object, - frontmatter: fm, - } + targets = ['astro', 'frontmatter'] break } case 'nuxt': { - file.data = fm + targets = undefined break } - default: { file.data = fm } + default: { + targets = options.target + } } + + let input = file.data as Record + if (targets) { + for (const target of targets) { + try { + input = input[target] as Record + } + catch { + input = {} + } + } + } + + const output = transform( + input, + [ + ...options.presets, + ...(options.strict ? [strict(options.strict)] : []), + ], + ) + + file.data = targets + ? { + ...file.data, + ...targets.reduceRight((output, key) => ({ [key]: output }), output), + } + : output } diff --git a/packages/remark-fff/src/types.ts b/packages/remark-fff/src/types.ts index 42f9174..1c844a5 100644 --- a/packages/remark-fff/src/types.ts +++ b/packages/remark-fff/src/types.ts @@ -1,5 +1,4 @@ import type { - FFFFlavoredFrontmatter, FFFTransformPreset, StrictPresetOptions, } from 'fff-flavored-frontmatter' @@ -11,30 +10,18 @@ import type { export interface RemarkFFFOptions { presets: FFFTransformPreset[] strict?: StrictPresetOptions + /** + * Replacement target for Remark FFF. + * @example + * ```ts + * // astro: file.data.astro.frontmatter + * const target = ['astro', 'frontmatter'] // file.data['astro']['frontmatter'] + * // mdsvex: file.data.fm + * const target = ['fm'] // file.data['fm'] + * // nuxt: file.data + * const target = undefined // file.data + * ``` + */ // eslint-disable-next-line @typescript-eslint/ban-types - target: 'astro' | 'mdsvex' | 'nuxt' | (string & {}) + target?: 'astro' | 'mdsvex' | 'nuxt' | string[] } - -/** - * Internal Post Data Type. - * @internal - */ -export type _Post = - | /** MDsveX */ { - data: { - astro: { - frontmatter: FFFFlavoredFrontmatter & Record - } - fm: never - } - filename: never - path: string - } - | /** Astro */ { - data: { - astro: never - fm: FFFFlavoredFrontmatter & Record - } - filename: string - path: never - } diff --git a/packages/remark-fff/test/frontmatter.spec.ts b/packages/remark-fff/test/frontmatter.spec.ts index 7936f67..95b8e7c 100644 --- a/packages/remark-fff/test/frontmatter.spec.ts +++ b/packages/remark-fff/test/frontmatter.spec.ts @@ -131,4 +131,27 @@ describe('remark-fff strict mode', () => { .processSync(file).data as { fm: FFFFlavoredFrontmatter } expect(fm.image).toEqual('https://fff.js.org/glowing_star.svg') }) + it('custom nested target', () => { + const file = new VFile({ + data: { + a: { + b: { + c: { + d: { + date: '2023-12-25', + }, + }, + }, + }, + }, + }) + const data = remark() + .use(remarkFrontmatter) + .use(remarkFFF, { + presets: [{ created: 'date' }], + target: ['a', 'b', 'c', 'd'], + }) + .processSync(file).data as { a: { b: { c: { d: FFFFlavoredFrontmatter } } } } + expect(data.a.b.c.d.created).toEqual('2023-12-25') + }) })