mdeval 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -271,7 +271,7 @@ pre-commit:
271
271
  glob: ["*.md", "**/*.md"]
272
272
  run: |
273
273
  files=$(npx mdeval "**/*.md")
274
- [ -n "$files" ] && git add $files
274
+ [ -z "$files" ] || git add $files
275
275
  ```
276
276
 
277
277
  `glob` makes the hook a no-op when no Markdown files are staged. mdeval prints the path of each file it rewrites to stdout, so `git add $files` re-stages only the files it actually updated. Note: `$files` relies on shell word-splitting, so this assumes `.md` paths without spaces.
package/dist/cli.mjs CHANGED
@@ -1,3 +1,8 @@
1
1
  #!/usr/bin/env node
2
- var M=Object.defineProperty;var l=(o,r)=>M(o,"name",{value:r,configurable:!0});import m from"node:fs/promises";import x from"node:path";import{cli as O}from"cleye";import{glob as S}from"tinyglobby";import"./loader.mjs";import{p as d,b as _,E as b,M as f,C,a as u,c as P,i as R}from"./parse-markdown-wnFVEAED.mjs";import{pathToFileURL as $}from"node:url";import"node:module";import"./runtime.mjs";import"zx";import"micromark";const k=l(o=>{if(o==null)throw new Error(`Cannot interpolate ${o} \u2014 this is likely a bug in your script`);return typeof o=="string"?o:typeof o=="object"?Symbol.toPrimitive in o?String(o):JSON.stringify(o):String(o)},"coerceValue"),N=l(async(o,r)=>{const{markers:t}=d(o);if(t.length===0)return o;const i=await import($(r).href),n=_(t),w=await Promise.all(Array.from(n).map(async([e,p])=>{const s=k(await i[`${b}${p}`]);if(s.includes(f)||s.includes(`${C}
3
- `)||s.includes(u))throw new Error(`Expression "${e}" produced a value containing mdeval comment syntax, which would corrupt the document on re-parse`);return s})),a=[];let c=0;for(const e of t){const p=f.length+e.expression.length+P.length,s=e.start+p,E=e.end-u.length,y=n.get(e.expression);a.push(o.slice(c,s),w[y]),c=E}return a.push(o.slice(c)),a.join("")},"processSource"),T=O({name:"mdeval",parameters:["<files...>"]}),g=T._.files,v=g.some(o=>o.includes("node_modules")),h=await S(g,{ignore:v?[]:["**/node_modules/**"]});h.length===0&&(console.error("No files matched the given patterns"),process.exit(1)),await Promise.all(h.map(async o=>{try{const r=x.resolve(o),t=await m.readFile(r,"utf8"),i=d(t);R(t,i)&&console.warn(`Warning: ${o} has no markdown content outside of mdeval blocks`);const n=await N(t,r);n!==t&&(await m.writeFile(r,n,"utf8"),console.log(o))}catch(r){console.error(`Error processing ${o}:`,r instanceof Error?r.message:r),process.exitCode=1}}));
2
+ var C=Object.defineProperty;var a=(t,e)=>C(t,"name",{value:e,configurable:!0});import h from"node:fs/promises";import E from"node:path";import{cli as M}from"cleye";import{glob as N}from"tinyglobby";import{yellow as $}from"ansis";import"./loader.mjs";import{p as g,b as R,E as T,M as k,C as m,a as d,c as A,i as F}from"./parse-markdown-wnFVEAED.mjs";import{pathToFileURL as P}from"node:url";import{fromMarkdown as S}from"mdast-util-from-markdown";import{gfmFootnote as _}from"micromark-extension-gfm-footnote";import{gfmFootnoteFromMarkdown as I}from"mdast-util-gfm-footnote";import{gfmTable as W}from"micromark-extension-gfm-table";import{gfmTableFromMarkdown as V}from"mdast-util-gfm-table";import{toHast as H}from"mdast-util-to-hast";import{visitParents as X}from"unist-util-visit-parents";import{parseFragment as j}from"parse5";import"node:module";import"./runtime.mjs";import"zx";import"micromark";const G=a(t=>{if(t==null)throw new Error(`Cannot interpolate ${t} \u2014 this is likely a bug in your script`);return typeof t=="string"?t:typeof t=="object"?Symbol.toPrimitive in t?String(t):JSON.stringify(t):String(t)},"coerceValue"),K=a(async(t,e)=>{const{markers:o}=g(t);if(o.length===0)return t;const n=await import(P(e).href),s=R(o),r=await Promise.all(Array.from(s).map(async([l,f])=>{const u=G(await n[`${T}${f}`]);if(u.includes(k)||u.includes(`${m}
3
+ `)||u.includes(d))throw new Error(`Expression "${l}" produced a value containing mdeval comment syntax, which would corrupt the document on re-parse`);return u})),i=[];let c=0;for(const l of o){const f=k.length+l.expression.length+A.length,u=l.start+f,x=l.end-d.length,b=s.get(l.expression);i.push(t.slice(c,u),r[b]),c=x}return i.push(t.slice(c)),i.join("")},"processSource"),B=a(t=>{const e=[];for(let o=0;o<t.length;o+=1)t[o]===`
4
+ `&&e.push(o);return e},"buildLineIndex"),D=a((t,e)=>{let o=0,n=t.length;for(;o<n;){const r=Math.floor((o+n)/2);t[r]<e?o=r+1:n=r}const s=o===0?-1:t[o-1];return{line:o+1,column:e-s}},"offsetToLineColumn"),w=a((t,e,o,n)=>{let s=t,r=e;for(let i=0;i<n;i+=1)o[i]===`
5
+ `?(s+=1,r=1):r+=1;return{line:s,column:r}},"advanceByValue"),J=a((t,e)=>{if(!t.startsWith(m,e))return!1;const o=t[e+m.length];return o===" "||o===`
6
+ `?!0:o==="\r"&&t[e+m.length+1]===`
7
+ `},"isMarkerOpening"),p=a((t,e=0,o=t.length)=>{const n=[];let s=0,r=e;for(;r<o;){const i=t.indexOf("<!--",r);if(i===-1||i>=o)break;J(t,i)?(n.push(i),s+=1,r=i+m.length):t.startsWith(d,i)?(s>0?s-=1:n.push(i),r=i+d.length):r=i+4}return n},"findMarkerLeaks"),U=a((t,e,o)=>{if(!t.attrs||!t.sourceCodeLocation?.attrs)return[];const n=[];for(const s of t.attrs){const r=t.sourceCodeLocation.attrs[s.name];if(!r)continue;const i=e+r.startOffset,{line:c,column:l}=o(i);for(const f of p(s.value))n.push({line:c,column:l})}return n},"attributeLeaks"),q=a((t,e,o)=>{const{value:n}=t;if(t.nodeName!=="#text"||typeof n!="string"||t.sourceCodeLocation?.startOffset===void 0)return[];const s=e+t.sourceCodeLocation.startOffset,r=o(s);return p(n).map(i=>{const{line:c,column:l}=w(r.line,r.column,n,i);return{line:c,column:l}})},"textLeaks"),z=a((t,e,o,n)=>{const s=t.slice(e,o),r=j(s,{sourceCodeLocationInfo:!0}),i=[],c=a(l=>{i.push(...U(l,e,n),...q(l,e,n));for(const f of l.childNodes??[])c(f)},"visit");return c(r),i},"findRawHtmlLeaks"),Q=a(t=>{let e=!1;for(const o of t){if(o.tagName==="pre")return"code block";o.tagName==="code"&&(e=!0)}return e?"inline code":"text"},"classifyTextLeak"),Y=a((t,e)=>e==="alt"?"image alt":t.tagName==="a"?"link title":"image title","classifyAttributeLeak"),v=a(t=>{const e=t.position?.start.offset,o=t.position?.end.offset;if(!(e===void 0||o===void 0))return{startOffset:e,endOffset:o,startLine:t.position?.start.line,startColumn:t.position?.start.column}},"rangeOf"),Z=a((t,e)=>{const o=v(t);if(o)return o;for(let n=e.length-1;n>=0;n-=1){const s=v(e[n]);if(s)return s}return{}},"positionRange"),tt=a((t,e,o)=>{if(e.startOffset!==void 0){if(o==="code block"){const n=t[e.startOffset];if(n===" "||n===" "){let r=e.startOffset;for(;t[r]===" "||t[r]===" ";)r+=1;return r}const s=t.indexOf(`
8
+ `,e.startOffset);return s===-1?e.startOffset:s+1}if(o==="inline code"){let n=e.startOffset;for(;t[n]==="`";)n+=1;return n}return e.startOffset}},"findContentStart"),et=a((t,e,o)=>t.map(n=>{const{line:s,column:r}=e(n);return{kind:o,line:s,column:r}}),"mapOffsetsToLeaks"),ot=a((t,e,o)=>e===void 0?{line:t.startLine??1,column:t.startColumn??1}:o(e),"resolveContentStart"),nt=a((t,e,o,n)=>e.map(s=>{const{line:r,column:i}=w(o.line,o.column,t,s);return{kind:n,line:r,column:i}}),"valueWalkLeaks"),rt=a((t,e,o,n,s)=>{const r=o.value??"";if(!r.includes("mdeval"))return[];const i=p(r);if(i.length===0)return[];const c=Z(o,n),l=tt(t,c,s);if(l!==void 0&&c.endOffset!==void 0){const u=p(t,l,c.endOffset);if(u.length===i.length)return et(u,e,s)}const f=ot(c,l,e);return nt(r,i,f,s)},"collectTextNodeLeaks"),st=a((t,e,o,n)=>{if(!o.includes("mdeval"))return[];const s=p(o);if(s.length===0)return[];const r=e.position?.start.offset??-1,{line:i,column:c}=r===-1?{line:e.position?.start.line??1,column:e.position?.start.column??1}:t(r);return s.map(()=>({kind:n,line:i,column:c}))},"collectAttributeLeaks"),it=a((t,e,o,n)=>o.type!=="text"||typeof o.value!="string"?[]:rt(t,e,o,n,Q(n)),"textNodeLeaks"),at=a((t,e,o)=>{if(o.type!=="raw"||typeof o.value!="string")return[];const n=o.position?.start.offset,s=o.position?.end.offset;return n===void 0||s===void 0?[]:z(t,n,s,e).map(r=>({kind:"raw html",...r}))},"rawNodeLeaks"),ct=a((t,e)=>{if(e.type!=="element"||!e.properties)return[];const o=[];for(const n of["alt","title"]){const s=e.properties[n];if(typeof s=="string"){const r=Y(e,n);o.push(...st(t,e,s,r))}}return o},"elementAttributeLeaks"),lt=a(t=>{if(!t.includes("mdeval"))return[];const e=t.codePointAt(0)===65279?t.slice(1):t,o=B(e),n=a(c=>D(o,c),"point"),s=S(e,{extensions:[_(),W()],mdastExtensions:[I(),V()]}),r=[],i=H(s,{allowDangerousHtml:!0});return X(i,(c,l)=>{const f=c;r.push(...it(e,n,f,l),...at(e,n,f),...ct(n,f))}),r},"findRenderedLeaks"),L=$("Warning:"),ft=M({name:"mdeval",parameters:["<files...>"]}),O=ft._.files,ut=O.some(t=>t.includes("node_modules")),y=await N(O,{ignore:ut?[]:["**/node_modules/**"]});y.length===0&&(console.error("No files matched the given patterns"),process.exit(1)),await Promise.all(y.map(async t=>{try{const e=E.resolve(t),o=await h.readFile(e,"utf8"),n=g(o);F(o,n)&&console.warn(`${L} ${t} has no markdown content outside of mdeval blocks`);const s=await K(o,e);s!==o&&(await h.writeFile(e,s,"utf8"),console.log(t));for(const r of lt(s))console.warn(`${L} ${t}:${r.line}:${r.column} mdeval marker leaks into rendered ${r.kind}`)}catch(e){console.error(`Error processing ${t}:`,e instanceof Error?e.message:e),process.exitCode=1}}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdeval",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Evaluate JavaScript in markdown HTML comments and interpolate results in-place",
5
5
  "keywords": [
6
6
  "markdown",
@@ -29,13 +29,22 @@
29
29
  "#md-loader": "./dist/md-loader.mjs"
30
30
  },
31
31
  "engines": {
32
- "node": ">=20"
32
+ "node": ">=20.19"
33
33
  },
34
34
  "dependencies": {
35
35
  "@jridgewell/gen-mapping": "^0.3.13",
36
+ "ansis": "^4.3.0",
36
37
  "cleye": "^2.3.0",
38
+ "mdast-util-from-markdown": "^2.0.3",
39
+ "mdast-util-gfm-footnote": "^2.1.0",
40
+ "mdast-util-gfm-table": "^2.0.0",
41
+ "mdast-util-to-hast": "^13.2.1",
37
42
  "micromark": "^4.0.2",
43
+ "micromark-extension-gfm-footnote": "^2.1.0",
44
+ "micromark-extension-gfm-table": "^2.1.1",
45
+ "parse5": "^8.0.1",
38
46
  "tinyglobby": "^0.2.15",
47
+ "unist-util-visit-parents": "^6.0.2",
39
48
  "zx": "8.8.5-lite"
40
49
  }
41
50
  }
@@ -266,7 +266,7 @@ pre-commit:
266
266
  glob: ["*.md", "**/*.md"]
267
267
  run: |
268
268
  files=$(npx mdeval "**/*.md")
269
- [ -n "$files" ] && git add $files
269
+ [ -z "$files" ] || git add $files
270
270
  ```
271
271
 
272
272
  `git add $files` re-stages only the files mdeval actually rewrote. Assumes `.md` paths without spaces.