From 2b81d16a93e223d9c7bd0b0622768c86b325399b Mon Sep 17 00:00:00 2001 From: "N. V. Lang" Date: Thu, 18 Jul 2024 07:11:35 +0200 Subject: [PATCH] feat: export frontmatter in one `metadata` object --- src/utils/frontmatter.ts | 10 +- .../unit/base/Sveltex/sveltex.script.test.ts | 6 +- .../MathHandler/MathHandler.katex.test.ts | 1 - .../MathHandler/MathHandler.mathjax.test.ts | 2 - tests/unit/utils/frontmatter.test.ts | 230 +++++++++++------- 5 files changed, 149 insertions(+), 100 deletions(-) diff --git a/src/utils/frontmatter.ts b/src/utils/frontmatter.ts index 65070a4..f3c6819 100644 --- a/src/utils/frontmatter.ts +++ b/src/utils/frontmatter.ts @@ -252,11 +252,15 @@ export function handleFrontmatter(snippet: ProcessableSnippet<'frontmatter'>): { const { title, base, noscript, link, meta, imports } = frontmatter; Object.entries(frontmatter).forEach(([key, value]) => { - scriptModuleLines.push( - `export const ${key} = ${JSON.stringify(value)};`, - ); + scriptModuleLines.push(`${key}: ${JSON.stringify(value)},`); + scriptLines.push(`const ${key} = ${JSON.stringify(value)};`); }); + if (scriptModuleLines.length > 0) { + scriptModuleLines.unshift('export const metadata = {'); + scriptModuleLines.push('};'); + } + // Imports if ( imports && diff --git a/tests/unit/base/Sveltex/sveltex.script.test.ts b/tests/unit/base/Sveltex/sveltex.script.test.ts index 29ed175..5994cdb 100644 --- a/tests/unit/base/Sveltex/sveltex.script.test.ts +++ b/tests/unit/base/Sveltex/sveltex.script.test.ts @@ -160,7 +160,7 @@ describe('Sveltex', () => { filename: '9ae17b43-d19c-4ca3-9772-36e506ffb4a5.sveltex', }); expect((scriptModuleOut as Processed).code).toContain( - 'export const foo = "bar";\nexport const author = "Jane Doe";\nexport const title = "Example";\nexport const meta = [{"name":"author","content":"Jane Doe"}];\n', + 'export const metadata = {\nfoo: "bar",\nauthor: "Jane Doe",\ntitle: "Example",\nmeta: [{"name":"author","content":"Jane Doe"}],\n};', ); existsSync.mockReset(); @@ -283,7 +283,7 @@ describe('Sveltex', () => { filename: 'a0dcf7dd-cabd-4816-a963-c30fc654ff34.sveltex', }); expect((scriptOut as Processed).code).toMatch( - /^\s*import Example from '\$lib\/components\/Example.svelte';\s*$/, + /^\s*const imports = \[\{"\$lib\/components\/Example.svelte":"Example;"\}\];\n+import Example from '\$lib\/components\/Example.svelte';\s*$/, ); const scriptModuleOut = await sp.script({ @@ -293,7 +293,7 @@ describe('Sveltex', () => { filename: 'a0dcf7dd-cabd-4816-a963-c30fc654ff34.sveltex', }); expect((scriptModuleOut as Processed).code).toContain( - 'export const imports = [{"$lib/components/Example.svelte":"Example;"}];', + 'export const metadata = {\nimports: [{"$lib/components/Example.svelte":"Example;"}],\n};', ); existsSync.mockReset(); }); diff --git a/tests/unit/handlers/MathHandler/MathHandler.katex.test.ts b/tests/unit/handlers/MathHandler/MathHandler.katex.test.ts index 1e77e66..6c352c1 100644 --- a/tests/unit/handlers/MathHandler/MathHandler.katex.test.ts +++ b/tests/unit/handlers/MathHandler/MathHandler.katex.test.ts @@ -10,7 +10,6 @@ import { } from 'vitest'; import { MathHandler } from '$handlers/MathHandler.js'; import { spy } from '$tests/unit/fixtures.js'; -import { v4 as uuid } from 'uuid'; import type { MathConfiguration } from '$types/handlers/Math.js'; function fixture() { diff --git a/tests/unit/handlers/MathHandler/MathHandler.mathjax.test.ts b/tests/unit/handlers/MathHandler/MathHandler.mathjax.test.ts index 2cef75a..8487a7a 100644 --- a/tests/unit/handlers/MathHandler/MathHandler.mathjax.test.ts +++ b/tests/unit/handlers/MathHandler/MathHandler.mathjax.test.ts @@ -10,8 +10,6 @@ import { } from 'vitest'; import { MathHandler } from '$handlers/MathHandler.js'; import { spy } from '$tests/unit/fixtures.js'; -import { v4 as uuid } from 'uuid'; -import { consoles } from '$utils/debug.js'; import type { SupportedCdn } from '$types/handlers/Css.js'; import type { PossibleMathCssApproach } from '$types/handlers/Math.js'; import { sveltex } from '$base/Sveltex.js'; diff --git a/tests/unit/utils/frontmatter.test.ts b/tests/unit/utils/frontmatter.test.ts index cce2c71..e2ca009 100644 --- a/tests/unit/utils/frontmatter.test.ts +++ b/tests/unit/utils/frontmatter.test.ts @@ -339,6 +339,9 @@ describe('handleFrontmatter()', () => { innerContent: undefined, optionsForProcessor: { type: 'yaml' }, }, + headLines: [], + scriptLines: [], + scriptModuleLines: [], }, { label: 'foo: bar', @@ -346,70 +349,83 @@ describe('handleFrontmatter()', () => { innerContent: 'foo: bar', optionsForProcessor: { type: 'yaml' }, }, - scriptModuleLines: ['export const foo = "bar";'], + headLines: [], + scriptLines: ['const foo = "bar";'], + scriptModuleLines: [ + 'export const metadata = {', + 'foo: "bar",', + '};', + ], }, { label: 'base', snippet: { - innerContent: [ - 'base:', - ' href: https://example.com', - ' target: _blank', - ].join('\n'), + innerContent: + 'base:\n href: https://example.com\n target: _blank', optionsForProcessor: { type: 'yaml' }, }, headLines: [''], + scriptLines: [ + 'const base = {"href":"https://example.com","target":"_blank"};', + ], scriptModuleLines: [ - 'export const base = {"href":"https://example.com","target":"_blank"};', + 'export const metadata = {', + 'base: {"href":"https://example.com","target":"_blank"},', + '};', ], }, { label: 'base (string)', snippet: { - innerContent: ['base: https://example.com'].join('\n'), + innerContent: 'base: https://example.com', optionsForProcessor: { type: 'yaml' }, }, headLines: [''], + scriptLines: ['const base = {"href":"https://example.com"};'], scriptModuleLines: [ - 'export const base = {"href":"https://example.com"};', + 'export const metadata = {', + 'base: {"href":"https://example.com"},', + '};', ], }, { label: 'base (invalid target)', snippet: { - innerContent: [ - 'base:', - ' href: https://example.com', - ' target: 123', - ].join('\n'), + innerContent: + 'base:\n href: https://example.com\n target: 123', optionsForProcessor: { type: 'yaml' }, }, headLines: [''], + scriptLines: ['const base = {"href":"https://example.com"};'], scriptModuleLines: [ - 'export const base = {"href":"https://example.com"};', + 'export const metadata = {', + 'base: {"href":"https://example.com"},', + '};', ], }, { label: 'base (invalid href)', snippet: { - innerContent: ['base:', ' href: 123', ' target: _blank'].join( - '\n', - ), + innerContent: 'base:\n href: 123\n target: _blank', optionsForProcessor: { type: 'yaml' }, }, headLines: [''], - scriptModuleLines: ['export const base = {"target":"_blank"};'], + scriptLines: ['const base = {"target":"_blank"};'], + scriptModuleLines: [ + 'export const metadata = {', + 'base: {"target":"_blank"},', + '};', + ], }, { label: 'meta object', snippet: { - innerContent: [ - 'author: ...', - 'meta:', - ' author: Jane Doe', - ' description: ...', + innerContent: + 'author: ...\n' + + 'meta:\n' + + ' author: Jane Doe\n' + + ' description: ...\n' + ' default-style: styles.css', - ].join('\n'), optionsForProcessor: { type: 'yaml' }, }, headLines: [ @@ -417,114 +433,132 @@ describe('handleFrontmatter()', () => { '', '', ], + scriptLines: [ + 'const author = "...";', + 'const meta = [{"name":"author","content":"Jane Doe"},{"name":"description","content":"..."},{"http-equiv":"default-style","content":"styles.css"}];', + ], scriptModuleLines: [ - 'export const author = "...";', - 'export const meta = [{"name":"author","content":"Jane Doe"},{"name":"description","content":"..."},{"http-equiv":"default-style","content":"styles.css"}];', + 'export const metadata = {', + 'author: "...",', + 'meta: [{"name":"author","content":"Jane Doe"},{"name":"description","content":"..."},{"http-equiv":"default-style","content":"styles.css"}],', + '};', ], }, { label: 'meta array', snippet: { - innerContent: [ - 'author: ...', - 'meta:', - '- name: author', - ' content: Jane Doe', - ].join('\n'), + innerContent: + 'author: ...\nmeta:\n- name: author\n content: Jane Doe', optionsForProcessor: { type: 'yaml' }, }, headLines: [''], + scriptLines: [ + 'const author = "...";', + 'const meta = [{"name":"author","content":"Jane Doe"}];', + ], scriptModuleLines: [ - 'export const author = "...";', - 'export const meta = [{"name":"author","content":"Jane Doe"}];', + 'export const metadata = {', + 'author: "...",', + 'meta: [{"name":"author","content":"Jane Doe"}],', + '};', ], }, { label: 'meta array (no content)', snippet: { - innerContent: ['meta:', '- name: author'].join('\n'), + innerContent: 'meta:\n- name: author', optionsForProcessor: { type: 'yaml' }, }, + headLines: [], + scriptLines: [], + scriptModuleLines: [], }, { label: 'meta object + keywords array', snippet: { - innerContent: [ - 'meta:', - ' description: This is a test page.', - ' keywords:', - ' - a', - ' - b', - ].join('\n'), + innerContent: + 'meta:\n description: This is a test page.\n keywords:\n - a\n - b', optionsForProcessor: { type: 'yaml' }, }, headLines: [ '', '', ], + scriptLines: [ + 'const meta = [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"a, b"}];', + ], scriptModuleLines: [ - 'export const meta = [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"a, b"}];', + 'export const metadata = {', + 'meta: [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"a, b"}],', + '};', ], }, { label: 'meta array + keywords array', snippet: { - innerContent: [ - 'meta:', - '- name: description', - ' content: This is a test page.', - '- name: keywords', - ' content:', - ' - a', + innerContent: + 'meta:\n' + + '- name: description\n' + + ' content: This is a test page.\n' + + '- name: keywords\n' + + ' content:\n' + + ' - a\n' + ' - b', - ].join('\n'), optionsForProcessor: { type: 'yaml' }, }, headLines: [ '', '', ], + scriptLines: [ + 'const meta = [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"a, b"}];', + ], scriptModuleLines: [ - 'export const meta = [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"a, b"}];', + 'export const metadata = {', + 'meta: [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"a, b"}],', + '};', ], }, { label: 'last value takes precedence', snippet: { - innerContent: [ - 'meta:', - '- name: description', - ' content: ...', - '- name: description', - ' content: This is a test page.', - '- name: keywords', - ' content:', - ' - a', - ' - b', - '- name: keywords', + innerContent: + 'meta:\n' + + '- name: description\n' + + ' content: ...\n' + + '- name: description\n' + + ' content: This is a test page.\n' + + '- name: keywords\n' + + ' content:\n' + + ' - a\n' + + ' - b\n' + + '- name: keywords\n' + ' content: c, d', - ].join('\n'), optionsForProcessor: { type: 'yaml' }, }, headLines: [ '', '', ], + scriptLines: [ + 'const meta = [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"c, d"}];', + ], scriptModuleLines: [ - 'export const meta = [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"c, d"}];', + 'export const metadata = {', + 'meta: [{"name":"description","content":"This is a test page."},{"name":"keywords","content":"c, d"}],', + '};', ], }, { label: 'title + links', snippet: { - innerContent: [ - 'title: ...', - 'link:', - '- rel: stylesheet', - ' href: styles.css', - '- rel: stylesheet', + innerContent: + 'title: ...\n' + + 'link:\n' + + '- rel: stylesheet\n' + + ' href: styles.css\n' + + '- rel: stylesheet\n' + ' href: styles2.css', - ].join('\n'), optionsForProcessor: { type: 'yaml' }, }, headLines: [ @@ -532,54 +566,68 @@ describe('handleFrontmatter()', () => { '', '', ], + scriptLines: [ + 'const title = "...";', + 'const link = [{"rel":"stylesheet","href":"styles.css"},{"rel":"stylesheet","href":"styles2.css"}];', + ], scriptModuleLines: [ - 'export const title = "...";', - 'export const link = [{"rel":"stylesheet","href":"styles.css"},{"rel":"stylesheet","href":"styles2.css"}];', + 'export const metadata = {', + 'title: "...",', + 'link: [{"rel":"stylesheet","href":"styles.css"},{"rel":"stylesheet","href":"styles2.css"}],', + '};', ], }, { label: 'noscript', snippet: { - innerContent: ['noscript: ...'].join('\n'), + innerContent: 'noscript: ...', optionsForProcessor: { type: 'yaml' }, }, headLines: [''], - scriptModuleLines: ['export const noscript = "...";'], + scriptLines: ['const noscript = "...";'], + scriptModuleLines: [ + 'export const metadata = {', + 'noscript: "...",', + '};', + ], }, { label: 'http-equiv with array', snippet: { - innerContent: [ - 'meta:', - ' default-style:', - ' - a', - ' - b', - ].join('\n'), + innerContent: 'meta:\n default-style:\n - a\n - b', optionsForProcessor: { type: 'yaml' }, }, headLines: [''], + scriptLines: [ + 'const meta = [{"http-equiv":"default-style","content":"a, b"}];', + ], scriptModuleLines: [ - 'export const meta = [{"http-equiv":"default-style","content":"a, b"}];', + 'export const metadata = {', + 'meta: [{"http-equiv":"default-style","content":"a, b"}],', + '};', ], }, { label: 'imports', snippet: { - innerContent: [ - 'imports:', - ' $lib/utils.js:', - ' - b', - ' - c', + innerContent: + 'imports:\n' + + ' $lib/utils.js:\n' + + ' - b\n' + + ' - c\n' + ' ./Something.svelte: Something', - ].join('\n'), optionsForProcessor: { type: 'yaml' }, }, + headLines: [], scriptLines: [ + 'const imports = {"$lib/utils.js":["b","c"],"./Something.svelte":"Something"};', "import { b, c } from '$lib/utils.js';", "import Something from './Something.svelte';", ], scriptModuleLines: [ - 'export const imports = {"$lib/utils.js":["b","c"],"./Something.svelte":"Something"};', + 'export const metadata = {', + 'imports: {"$lib/utils.js":["b","c"],"./Something.svelte":"Something"},', + '};', ], }, ] as {