Comparing version 0.4.1-beta.5 to 0.4.1-beta.6
{ | ||
"name": "mdsvex", | ||
"version": "0.4.1-beta.5", | ||
"version": "0.4.1-beta.6", | ||
"description": "Markdown preprocessor for Svelte", | ||
@@ -15,3 +15,2 @@ "main": "dist/main.cjs.js", | ||
"test:cov": "yarn lint && jest --verbose --coverage", | ||
"postinstall": "patch-package", | ||
"generate_files": "node -r esm ./test/_scripts/generate_markdown_html.js" | ||
@@ -32,6 +31,7 @@ }, | ||
"cheap-watch": "^1.0.2", | ||
"eslint": "^6.3.0", | ||
"eslint": "^6.6.0", | ||
"eslint-plugin-import": "^2.18.2", | ||
"esm": "^3.2.25", | ||
"highlight.js": "^9.15.10", | ||
"front-matter": "^3.0.2", | ||
"highlight.js": "^9.16.2", | ||
"jest-diff": "^24.9.0", | ||
@@ -42,3 +42,3 @@ "js-yaml": "^3.13.1", | ||
"postinstall-postinstall": "^2.0.0", | ||
"prettier": "^1.18.2", | ||
"prettier": "^1.19.1", | ||
"prettier-eslint": "^9.0.0", | ||
@@ -51,3 +51,3 @@ "rehype-slug": "^2.0.3", | ||
"remark-frontmatter": "^1.3.2", | ||
"remark-parse": "^7.0.1", | ||
"remark-parse": "^7.0.2", | ||
"remark-rehype": "^5.0.0", | ||
@@ -57,3 +57,3 @@ "remark-slug": "^5.1.2", | ||
"retext-smartypants": "^3.0.3", | ||
"rollup": "^1.20.3", | ||
"rollup": "^1.27.0", | ||
"rollup-plugin-commonjs": "^10.1.0", | ||
@@ -64,7 +64,7 @@ "rollup-plugin-json": "^4.0.0", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
"rollup-plugin-svelte": "^5.1.0", | ||
"svelte": "^3.9.1", | ||
"unified": "^8.4.1", | ||
"rollup-plugin-svelte": "^5.1.1", | ||
"svelte": "^3.14.1", | ||
"unified": "^8.4.2", | ||
"yarn": "^1.19.0", | ||
"zora": "^3.0.3" | ||
"zora": "^3.1.4" | ||
}, | ||
@@ -74,5 +74,3 @@ "peerDependencies": { | ||
}, | ||
"dependencies": { | ||
"patch-package": "^6.2.0" | ||
} | ||
"dependencies": {} | ||
} |
201
src/index.js
import unified from 'unified'; | ||
import markdown from 'remark-parse'; | ||
import external from 'remark-external-links'; | ||
import frontmatter from 'remark-frontmatter'; | ||
import remark2rehype from 'remark-rehype'; | ||
import hast_to_html from '@starptech/prettyhtml-hast-to-html'; | ||
import frontmatter from 'remark-frontmatter'; | ||
import visit from 'unist-util-visit'; | ||
import retext from 'retext'; | ||
import smartypants from 'retext-smartypants'; | ||
import external from 'remark-external-links'; | ||
import { mdsvex_parser } from './parsers/'; | ||
import { mdsvex_transformer } from './transformers/'; | ||
import { | ||
parse_yaml, | ||
escape_code, | ||
transform_hast, | ||
smartypants_transformer, | ||
} from './transformers/'; | ||
@@ -36,162 +37,2 @@ function stringify(options = {}) { | ||
function smartypants_processor(options = {}) { | ||
const processor = retext().use(smartypants, options); | ||
function transformer(tree) { | ||
visit(tree, 'text', node => { | ||
node.value = String(processor.processSync(node.value)); | ||
}); | ||
} | ||
return transformer; | ||
} | ||
const entites = [ | ||
[/</g, '<'], | ||
[/>/g, '>'], | ||
[/{/g, '{'], | ||
[/}/g, '}'], | ||
]; | ||
function code() { | ||
function transformer(tree) { | ||
visit(tree, 'code', node => { | ||
for (let i = 0; i < entites.length; i += 1) { | ||
node.value = node.value.replace(entites[i][0], entites[i][1]); | ||
} | ||
}); | ||
} | ||
return transformer; | ||
} | ||
const attrs = `(?:\\s{0,1}[a-zA-z]+=(?:"){0,1}[a-zA-Z0-9]+(?:"){0,1})*`; | ||
const RE_MODULE_SCRIPT = new RegExp( | ||
`^(<script` + | ||
attrs + | ||
`(?:\\s{0,1}(?:context)+=(?:"){0,1}(?:module)+(?:"){0,1}){1,}` + | ||
attrs + | ||
`>)[^]+?<\\/script>` | ||
); | ||
const RE_SCRIPT = new RegExp(`^(<script` + attrs + `>)[^]+?<\\/script>`); | ||
const RE_STYLES = new RegExp(`^(<style` + attrs + `>)[^]+?<\\/style>`); | ||
function html(layout) { | ||
function transformer(tree) { | ||
visit(tree, 'element', node => { | ||
if (node.tagName === 'a' && node.properties.href) { | ||
node.properties.href = node.properties.href | ||
.replace(/%7B/g, '{') | ||
.replace(/%7D/g, '}'); | ||
} | ||
if (node.tagName === 'img' && node.properties.src) { | ||
node.properties.src = node.properties.src | ||
.replace(/%7B/g, '{') | ||
.replace(/%7D/g, '}'); | ||
} | ||
}); | ||
if (!layout) return; | ||
// breaks positioning | ||
visit(tree, 'root', node => { | ||
const nodes = []; | ||
const instances = { | ||
match: false, | ||
nodes: [], | ||
}; | ||
const modules = { | ||
match: false, | ||
nodes: [], | ||
}; | ||
const styles = { | ||
match: false, | ||
nodes: [], | ||
}; | ||
// don't even ask | ||
children: for (let i = 0; i < node.children.length; i += 1) { | ||
if (node.children[i].type != 'raw' || !node.children[i].value) { | ||
nodes.push(node.children[i]); | ||
continue children; | ||
} | ||
let start = 0; | ||
let depth = 0; | ||
let started = false; | ||
for (let c = 0; c < node.children[i].value.length; c += 1) { | ||
if ( | ||
node.children[i].value[c] === '<' && | ||
node.children[i].value[c + 1] !== '/' | ||
) { | ||
depth += 1; | ||
started = true; | ||
} | ||
if ( | ||
node.children[i].value[c] === '<' && | ||
node.children[i].value[c + 1] === '/' | ||
) | ||
depth -= 1; | ||
if (started && depth === 0) { | ||
if (node.children[i].value[c] === '>') { | ||
const value = node.children[i].value | ||
.substring(start, c + 1) | ||
.trim(); | ||
let match; | ||
if ((match = RE_MODULE_SCRIPT.exec(value))) { | ||
modules.match = match; | ||
modules.nodes.push({ type: 'raw', meta: 'module', value }); | ||
} else if ((match = RE_SCRIPT.exec(value))) { | ||
instances.match = match; | ||
instances.nodes.push({ type: 'raw', meta: 'instance', value }); | ||
} else if ((match = RE_STYLES.exec(value))) { | ||
styles.match = match; | ||
styles.nodes.push({ type: 'raw', meta: 'style', value }); | ||
} else { | ||
nodes.push({ type: 'raw', value }); | ||
} | ||
start = c + 1; | ||
started = false; | ||
} | ||
} | ||
} | ||
} | ||
const _import = `import Layout_MDSVEX_DEFAULT from '${layout}';`; | ||
if (!instances.match) { | ||
instances.nodes.push({ | ||
type: 'raw', | ||
value: `\n<script>\n ${_import}\n</script>\n`, | ||
}); | ||
} else { | ||
instances.nodes[0].value = instances.nodes[0].value.replace( | ||
instances.match[1], | ||
`${instances.match[1]}\n ${_import}` | ||
); | ||
} | ||
// please clean this up | ||
node.children = [ | ||
...modules.nodes, | ||
{ type: 'raw', value: '\n' }, | ||
...instances.nodes, | ||
{ type: 'raw', value: '\n' }, | ||
...styles.nodes, | ||
{ type: 'raw', value: '\n' }, | ||
{ type: 'raw', value: '<Layout_MDSVEX_DEFAULT>' }, | ||
...nodes, | ||
{ type: 'raw', value: '</Layout_MDSVEX_DEFAULT>' }, | ||
]; | ||
}); | ||
} | ||
return transformer; | ||
} | ||
export function transform({ | ||
@@ -205,11 +46,11 @@ remarkPlugins = [], | ||
.use(markdown) | ||
.use(mdsvex_parser) | ||
.use(external, { target: false, rel: ['nofollow'] }) | ||
.use(code) | ||
.use(escape_code) | ||
.use(frontmatter) | ||
.use(mdsvex_parser) | ||
.use(mdsvex_transformer); | ||
.use(parse_yaml); | ||
if (smartypants) { | ||
toMDAST.use( | ||
smartypants_processor, | ||
smartypants_transformer, | ||
typeof smartypants === 'boolean' ? {} : smartypants | ||
@@ -219,4 +60,2 @@ ); | ||
// plugins : [ [plugin, opts] ] | [ plugin ] | ||
apply_plugins(remarkPlugins, toMDAST); | ||
@@ -229,3 +68,3 @@ | ||
}) | ||
.use(html, layout); | ||
.use(transform_hast, { layout }); | ||
@@ -257,2 +96,9 @@ apply_plugins(rehypePlugins, toHAST); | ||
} = defaults) => { | ||
const parser = transform({ | ||
remarkPlugins, | ||
rehypePlugins, | ||
smartypants, | ||
layout, | ||
}); | ||
return { | ||
@@ -262,9 +108,2 @@ markup: async ({ content, filename }) => { | ||
const parser = transform({ | ||
remarkPlugins, | ||
rehypePlugins, | ||
smartypants, | ||
layout, | ||
}); | ||
const parsed = await parser.process(content); | ||
@@ -271,0 +110,0 @@ |
@@ -1,3 +0,3 @@ | ||
import { parse_svelte_tag } from './svelte_tags'; | ||
import { parse_svelte_block } from './svelte_blocks'; | ||
import { parse_svelte_tag } from './svelte'; | ||
import { parse_svelte_block } from './svelte'; | ||
import { blockHtml } from './html_block'; | ||
@@ -4,0 +4,0 @@ |
@@ -0,5 +1,10 @@ | ||
import retext from 'retext'; | ||
import smartypants from 'retext-smartypants'; | ||
import visit from 'unist-util-visit'; | ||
import yaml from 'js-yaml'; | ||
import { parse } from 'svelte/compiler'; | ||
export function mdsvex_transformer() { | ||
// extract the yaml from 'yaml' nodes and put them in the vfil for later use | ||
export function parse_yaml() { | ||
return transformer; | ||
@@ -10,3 +15,3 @@ | ||
try { | ||
vFile.data = yaml.safeLoad(node.value); | ||
vFile.data.fm = yaml.safeLoad(node.value); | ||
} catch (e) { | ||
@@ -16,4 +21,223 @@ vFile.messages.push(['YAML failed to parse', e]); | ||
}); | ||
return tree; | ||
} | ||
} | ||
// in code nodes replace the character witrh the html entities | ||
// maybe I'll need more of these | ||
const entites = [ | ||
[/</g, '<'], | ||
[/>/g, '>'], | ||
[/{/g, '{'], | ||
[/}/g, '}'], | ||
]; | ||
export function escape_code() { | ||
function transformer(tree) { | ||
visit(tree, 'code', node => { | ||
for (let i = 0; i < entites.length; i += 1) { | ||
node.value = node.value.replace(entites[i][0], entites[i][1]); | ||
} | ||
}); | ||
} | ||
return transformer; | ||
} | ||
// special case - process nodes with retext and smarypants | ||
// retext plugins can't work generally due to the difficulties in converting between the two trees | ||
export function smartypants_transformer(options = {}) { | ||
const processor = retext().use(smartypants, options); | ||
function transformer(tree) { | ||
visit(tree, 'text', node => { | ||
node.value = String(processor.processSync(node.value)); | ||
}); | ||
} | ||
return transformer; | ||
} | ||
// regex for scripts and attributes | ||
const attrs = `(?:\\s{0,1}[a-zA-z]+=(?:"){0,1}[a-zA-Z0-9]+(?:"){0,1})*`; | ||
const context = `(?:\\s{0,1}context)=(?:"){0,1}module(?:"){0,1}`; | ||
const RE_BLANK = /^\n+$|^\s+$/; | ||
const RE_SCRIPT = new RegExp(`^(<script` + attrs + `>)`); | ||
const RE_MODULE_SCRIPT = new RegExp( | ||
`^(<script` + attrs + context + attrs + `>)` | ||
); | ||
export function transform_hast({ layout }) { | ||
return transformer; | ||
function transformer(tree, vFile) { | ||
// we need to keep { and } intact for svelte, so reverse the escaping in links and images | ||
visit(tree, 'element', node => { | ||
if (node.tagName === 'a' && node.properties.href) { | ||
node.properties.href = node.properties.href | ||
.replace(/%7B/g, '{') | ||
.replace(/%7D/g, '}'); | ||
} | ||
if (node.tagName === 'img' && node.properties.src) { | ||
node.properties.src = node.properties.src | ||
.replace(/%7B/g, '{') | ||
.replace(/%7D/g, '}'); | ||
} | ||
}); | ||
// the rest only applies to layouts and front matter | ||
// this currently breaks position data svelte preprocessors don't currently support sourcemaps | ||
// i'll fix this when they do | ||
if (!layout && !vFile.data.fm) return; | ||
visit(tree, 'root', node => { | ||
// since we are wrapping and replacing we need to keep track of the different component 'parts' | ||
// many special tags cannot be wrapped nor can style or script tags | ||
const parts = { | ||
special: [], | ||
html: [], | ||
instance: [], | ||
module: [], | ||
css: [], | ||
}; | ||
// iterate through all top level child nodes and assign them to the correct 'part' | ||
// anything that is a normal HAST node gets stored as HTML untouched | ||
// everything else gets parsed by the svelte parser | ||
children: for (let i = 0; i < node.children.length; i += 1) { | ||
if ( | ||
(node.children[i].type !== 'raw' && | ||
(node.children[i].type === 'text' && | ||
RE_BLANK.exec(node.children[i].value))) || | ||
!node.children[i].value | ||
) { | ||
if ( | ||
!parts.html[parts.html.length - 1] || | ||
!( | ||
RE_BLANK.exec(node.children[i].value) && | ||
RE_BLANK.exec(parts.html[parts.html.length - 1].value) | ||
) | ||
) { | ||
parts.html.push(node.children[i]); | ||
} | ||
continue children; | ||
} | ||
const result = parse(node.children[i].value); | ||
// svelte special tags that have to be top level | ||
const _parts = result.html.children.map(v => { | ||
if ( | ||
v.type === 'Options' || | ||
v.type === 'Head' || | ||
v.type === 'Window' || | ||
v.type === 'Body' | ||
) { | ||
return ['special', v.start, v.end]; | ||
} else { | ||
return ['html', v.start, v.end]; | ||
} | ||
}); | ||
// module scripts | ||
if (result.module) { | ||
_parts.push(['module', result.module.start, result.module.end]); | ||
} | ||
// style elements | ||
if (result.css) { | ||
_parts.push(['css', result.css.start, result.css.end]); | ||
} | ||
// instance scripts | ||
if (result.instance) { | ||
_parts.push(['instance', result.instance.start, result.instance.end]); | ||
} | ||
// sort them to ensure the array is in the order they appear in the source, no gaps | ||
// this might not be necessary any more, i forget | ||
const sorted = _parts.sort((a, b) => a[1] - b[1]); | ||
// push the nodes into the correct 'part' since they are sorted everything should be in the correct order | ||
sorted.forEach(next => { | ||
parts[next[0]].push({ | ||
type: 'raw', | ||
value: node.children[i].value.substring(next[1], next[2]), | ||
}); | ||
}); | ||
} | ||
const { special, html, instance, module: _module, css } = parts; | ||
const fm = | ||
vFile.data.fm && | ||
`export const metadata = ${JSON.stringify(vFile.data.fm)};`; | ||
const _layout = | ||
vFile.data.fm && vFile.data.fm.layout ? vFile.data.fm.layout : layout; | ||
const layout_import = | ||
_layout && `import Layout_MDSVEX_DEFAULT from '${_layout}';`; | ||
// add the layout if w are using one, resuing the existing script if one exists | ||
if (_layout && !instance[0]) { | ||
instance.push({ | ||
type: 'raw', | ||
value: `\n<script>\n\t${layout_import}\n</script>\n`, | ||
}); | ||
} else if (_layout) { | ||
instance[0].value = instance[0].value.replace( | ||
RE_SCRIPT, | ||
`$1\n\t${layout_import}` | ||
); | ||
} | ||
// inject the frontmatter into the module script if there is any, resuing the existing module script if one exists | ||
if (!_module[0] && fm) { | ||
_module.push({ | ||
type: 'raw', | ||
value: `<script context="module">\n\t${fm}\n</script>`, | ||
}); | ||
} else if (fm) { | ||
_module[0].value = _module[0].value.replace( | ||
RE_MODULE_SCRIPT, | ||
`$1\n\t${fm}` | ||
); | ||
} | ||
// smoosh it all together in an order that makes sense, | ||
// if using a layout we only wrap the html and nothing else | ||
node.children = [ | ||
..._module, | ||
{ type: 'raw', value: _module[0] ? '\n' : '' }, | ||
...instance, | ||
{ type: 'raw', value: instance[0] ? '\n' : '' }, | ||
...css, | ||
{ type: 'raw', value: css[0] ? '\n' : '' }, | ||
...special, | ||
{ type: 'raw', value: special[0] ? '\n' : '' }, | ||
{ | ||
type: 'raw', | ||
value: _layout | ||
? `<Layout_MDSVEX_DEFAULT${fm ? ' {...metadata}' : ''}>` | ||
: '', | ||
}, | ||
{ type: 'raw', value: '\n' }, | ||
...html, | ||
{ type: 'raw', value: '\n' }, | ||
{ type: 'raw', value: _layout ? '</Layout_MDSVEX_DEFAULT>' : '' }, | ||
]; | ||
}); | ||
} | ||
} |
@@ -20,3 +20,6 @@ import { | ||
const printBailout = message => { | ||
print('Bail out! Unhandled error.', message); | ||
// console.log(message); | ||
console.log(bgRed('Bail out! Unhandled error.')); | ||
console.log(message.data.stack); | ||
//print('Bail out! Unhandled error.', message.data, message.offset); | ||
}; | ||
@@ -50,3 +53,2 @@ | ||
const output = []; | ||
for await (const message of stream) { | ||
@@ -66,3 +68,3 @@ output.push(message); | ||
for (let i = 0; i < output.length; i++) { | ||
if (output[i].type === 'BAILOUT') printBailout(); | ||
if (output[i].type === 'BAIL_OUT') printBailout(output[i]); | ||
// directory | ||
@@ -69,0 +71,0 @@ if (output[i].offset === 0) { |
@@ -15,2 +15,3 @@ const { createHarness } = require('zora'); | ||
run(test, opts); | ||
report(harness); | ||
@@ -17,0 +18,0 @@ }; |
@@ -210,9 +210,9 @@ import { mdsvex } from '../../src/'; | ||
` | ||
<script> | ||
import Layout_MDSVEX_DEFAULT from 'path/to/layout'; | ||
import Layout_MDSVEX_DEFAULT from 'path/to/layout'; | ||
</script> | ||
<Layout_MDSVEX_DEFAULT><h1>hello</h1></Layout_MDSVEX_DEFAULT>`, | ||
<Layout_MDSVEX_DEFAULT> | ||
<h1>hello</h1> | ||
</Layout_MDSVEX_DEFAULT>`, | ||
output.code | ||
@@ -241,7 +241,70 @@ ); | ||
t.equal( | ||
` | ||
`<script> | ||
import Layout_MDSVEX_DEFAULT from 'path/to/layout'; | ||
export let x = 1; | ||
</script> | ||
<style> | ||
h1 { | ||
color: pink; | ||
} | ||
</style> | ||
<Layout_MDSVEX_DEFAULT> | ||
<h1>hello</h1> | ||
</Layout_MDSVEX_DEFAULT>`, | ||
output.code | ||
); | ||
}); | ||
test('custom layouts should work - when there are script tags with random attributes', async t => { | ||
const output = await mdsvex({ layout: 'path/to/layout' }).markup({ | ||
content: ` | ||
<script type="ts" lang=whatever thing="whatsit" doodaa=thingamabob> | ||
export let x = 1; | ||
</script> | ||
# hello | ||
<style> | ||
h1 { | ||
color: pink; | ||
} | ||
</style> | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script type="ts" lang=whatever thing="whatsit" doodaa=thingamabob> | ||
import Layout_MDSVEX_DEFAULT from 'path/to/layout'; | ||
export let x = 1; | ||
</script> | ||
<style> | ||
h1 { | ||
color: pink; | ||
} | ||
</style> | ||
<Layout_MDSVEX_DEFAULT> | ||
<h1>hello</h1> | ||
</Layout_MDSVEX_DEFAULT>`, | ||
output.code | ||
); | ||
}); | ||
test('custom layouts should work - when everything is in a random order', async t => { | ||
const output = await mdsvex({ layout: 'path/to/layout' }).markup({ | ||
content: ` | ||
# hello | ||
<script> | ||
import Layout_MDSVEX_DEFAULT from 'path/to/layout'; | ||
export let x = 1; | ||
</script> | ||
hello friends | ||
<svelte:window /> | ||
<style> | ||
@@ -252,4 +315,23 @@ h1 { | ||
</style> | ||
boo boo boo | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script> | ||
import Layout_MDSVEX_DEFAULT from 'path/to/layout'; | ||
export let x = 1; | ||
</script> | ||
<style> | ||
h1 { | ||
color: pink; | ||
} | ||
</style> | ||
<svelte:window /> | ||
<Layout_MDSVEX_DEFAULT> | ||
<h1>hello</h1> | ||
<p>hello friends</p> | ||
<p>boo boo boo</p> | ||
</Layout_MDSVEX_DEFAULT>`, | ||
@@ -259,2 +341,230 @@ output.code | ||
}); | ||
test('YAML front-matter should be injected into the component module script', async t => { | ||
const output = await mdsvex().markup({ | ||
content: `--- | ||
string: value | ||
string2: 'value2' | ||
array: [1, 2, 3] | ||
number: 999 | ||
--- | ||
# hello | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script context="module"> | ||
export const metadata = {"string":"value","string2":"value2","array":[1,2,3],"number":999}; | ||
</script> | ||
<h1>hello</h1> | ||
`, | ||
output.code | ||
); | ||
}); | ||
test('YAML front-matter should be injected into the component module script - even if there is already a module script', async t => { | ||
const output = await mdsvex().markup({ | ||
content: `--- | ||
string: value | ||
string2: 'value2' | ||
array: [1, 2, 3] | ||
number: 999 | ||
--- | ||
<script context="module"> | ||
let thing = 27; | ||
</script> | ||
# hello | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script context="module"> | ||
export const metadata = {"string":"value","string2":"value2","array":[1,2,3],"number":999}; | ||
let thing = 27; | ||
</script> | ||
<h1>hello</h1> | ||
`, | ||
output.code | ||
); | ||
}); | ||
test('YAML front-matter should be injected into the component module script - even if there is already a module script with unquoted attributes', async t => { | ||
const output = await mdsvex().markup({ | ||
content: `--- | ||
string: value | ||
string2: 'value2' | ||
array: [1, 2, 3] | ||
number: 999 | ||
--- | ||
<script context=module> | ||
let thing = 27; | ||
</script> | ||
# hello | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script context=module> | ||
export const metadata = {"string":"value","string2":"value2","array":[1,2,3],"number":999}; | ||
let thing = 27; | ||
</script> | ||
<h1>hello</h1> | ||
`, | ||
output.code | ||
); | ||
}); | ||
test('YAML front-matter should be injected into the component module script - even if there is already a module script with random attributes', async t => { | ||
const output = await mdsvex().markup({ | ||
content: `--- | ||
string: value | ||
string2: 'value2' | ||
array: [1, 2, 3] | ||
number: 999 | ||
--- | ||
<script type="ts" lang=whatever context=module thing="whatsit" doodaa=thingamabob> | ||
let thing = 27; | ||
</script> | ||
# hello | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script type="ts" lang=whatever context=module thing="whatsit" doodaa=thingamabob> | ||
export const metadata = {"string":"value","string2":"value2","array":[1,2,3],"number":999}; | ||
let thing = 27; | ||
</script> | ||
<h1>hello</h1> | ||
`, | ||
output.code | ||
); | ||
}); | ||
test('YAML front-matter should be injected passed to custom layouts', async t => { | ||
const output = await mdsvex({ layout: 'path/to/layout' }).markup({ | ||
content: `--- | ||
string: value | ||
string2: 'value2' | ||
array: [1, 2, 3] | ||
number: 999 | ||
--- | ||
<script context="module"> | ||
let thing = 27; | ||
</script> | ||
# hello | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script context="module"> | ||
export const metadata = {"string":"value","string2":"value2","array":[1,2,3],"number":999}; | ||
let thing = 27; | ||
</script> | ||
<script> | ||
import Layout_MDSVEX_DEFAULT from 'path/to/layout'; | ||
</script> | ||
<Layout_MDSVEX_DEFAULT {...metadata}> | ||
<h1>hello</h1> | ||
</Layout_MDSVEX_DEFAULT>`, | ||
output.code | ||
); | ||
}); | ||
test('Custom layout can be set via frontmatter', async t => { | ||
const output = await mdsvex().markup({ | ||
content: `--- | ||
layout: ./path/to/layout | ||
string: value | ||
string2: 'value2' | ||
array: [1, 2, 3] | ||
number: 999 | ||
--- | ||
<script context="module"> | ||
let thing = 27; | ||
</script> | ||
# hello | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script context="module"> | ||
export const metadata = {"layout":"./path/to/layout","string":"value","string2":"value2","array":[1,2,3],"number":999}; | ||
let thing = 27; | ||
</script> | ||
<script> | ||
import Layout_MDSVEX_DEFAULT from './path/to/layout'; | ||
</script> | ||
<Layout_MDSVEX_DEFAULT {...metadata}> | ||
<h1>hello</h1> | ||
</Layout_MDSVEX_DEFAULT>`, | ||
output.code | ||
); | ||
}); | ||
test('layouts provided via frontmatter should overwrite defaults', async t => { | ||
const output = await mdsvex({ layout: 'other/path/to/layout' }).markup({ | ||
content: `--- | ||
layout: ./path/to/layout | ||
string: value | ||
string2: 'value2' | ||
array: [1, 2, 3] | ||
number: 999 | ||
--- | ||
<script context="module"> | ||
let thing = 27; | ||
</script> | ||
# hello | ||
`, | ||
filename: 'file.svexy', | ||
}); | ||
t.equal( | ||
`<script context="module"> | ||
export const metadata = {"layout":"./path/to/layout","string":"value","string2":"value2","array":[1,2,3],"number":999}; | ||
let thing = 27; | ||
</script> | ||
<script> | ||
import Layout_MDSVEX_DEFAULT from './path/to/layout'; | ||
</script> | ||
<Layout_MDSVEX_DEFAULT {...metadata}> | ||
<h1>hello</h1> | ||
</Layout_MDSVEX_DEFAULT>`, | ||
output.code | ||
); | ||
}); | ||
} |
@@ -10,3 +10,2 @@ import { parse_svelte_block } from '../../src/parsers'; | ||
export default function(test) { | ||
// console.log(test); | ||
const svelte_blocks = [ | ||
@@ -95,3 +94,2 @@ [ | ||
}); | ||
// console.log('boo', name); | ||
} |
@@ -10,3 +10,2 @@ import { parse_svelte_tag } from '../../src/parsers'; | ||
export default function(test) { | ||
// console.log(test); | ||
const svelte_tags = [ | ||
@@ -13,0 +12,0 @@ ['component', 'svelte:component'], |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
2029407
1
71907
0
37
467
- Removedpatch-package@^6.2.0
- Removed@yarnpkg/lockfile@1.1.0(transitive)
- Removedansi-styles@4.3.0(transitive)
- Removedat-least-node@1.0.0(transitive)
- Removedbalanced-match@1.0.2(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedbraces@3.0.3(transitive)
- Removedchalk@4.1.2(transitive)
- Removedci-info@2.0.0(transitive)
- Removedcolor-convert@2.0.1(transitive)
- Removedcolor-name@1.1.4(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removedcross-spawn@6.0.6(transitive)
- Removedfill-range@7.1.1(transitive)
- Removedfind-yarn-workspace-root@2.0.0(transitive)
- Removedfs-extra@9.1.0(transitive)
- Removedfs.realpath@1.0.0(transitive)
- Removedglob@7.2.3(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removedhas-flag@4.0.0(transitive)
- Removedinflight@1.0.6(transitive)
- Removedinherits@2.0.4(transitive)
- Removedis-ci@2.0.0(transitive)
- Removedis-docker@2.2.1(transitive)
- Removedis-number@7.0.0(transitive)
- Removedis-wsl@2.2.0(transitive)
- Removedisexe@2.0.0(transitive)
- Removedjsonfile@6.1.0(transitive)
- Removedklaw-sync@6.0.0(transitive)
- Removedmicromatch@4.0.8(transitive)
- Removedminimatch@3.1.2(transitive)
- Removedminimist@1.2.8(transitive)
- Removednice-try@1.0.5(transitive)
- Removedonce@1.4.0(transitive)
- Removedopen@7.4.2(transitive)
- Removedos-tmpdir@1.0.2(transitive)
- Removedpatch-package@6.5.1(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedpath-key@2.0.1(transitive)
- Removedpicomatch@2.3.1(transitive)
- Removedrimraf@2.7.1(transitive)
- Removedsemver@5.7.2(transitive)
- Removedshebang-command@1.2.0(transitive)
- Removedshebang-regex@1.0.0(transitive)
- Removedslash@2.0.0(transitive)
- Removedsupports-color@7.2.0(transitive)
- Removedtmp@0.0.33(transitive)
- Removedto-regex-range@5.0.1(transitive)
- Removeduniversalify@2.0.1(transitive)
- Removedwhich@1.3.1(transitive)
- Removedwrappy@1.0.2(transitive)
- Removedyaml@1.10.2(transitive)