madr-lint 0.4.2 → 0.5.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#200](https://github.com/knktkc/madr-lint/pull/200) [`c67293d`](https://github.com/knktkc/madr-lint/commit/c67293dc6f3f94afe6e32180f4c86221f0d21d6d) Thanks [@knktkc](https://github.com/knktkc)! - Read `---js` and `---javascript` frontmatter that is a static object literal: strings, numbers, booleans, null, arrays, and nested objects, with comments, unquoted keys, and trailing commas. The block is parsed as data and never executed, so calls, variables, expressions, template literals, getters, methods, spread, and computed keys still fail with an error. `madr/supersedes-bidirectional` no longer offers a `--fix` for targets whose frontmatter is `---js` or `---json`, because inserting a YAML line would corrupt them.
8
+
9
+ ## 0.4.3
10
+
11
+ ### Patch Changes
12
+
13
+ - [`f854ca3`](https://github.com/knktkc/madr-lint/commit/f854ca3a84e2694307356117bfd23c9d5db3ef2c) Thanks [@knktkc](https://github.com/knktkc)! - Reject JavaScript frontmatter instead of evaluating it. A document that opens with `---js` or `---javascript` now fails with an error, and its frontmatter block is not executed.
14
+
3
15
  ## 0.4.2
4
16
 
5
17
  ### Patch Changes
package/dist/cli.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
 
2
- export { }
2
+ export { };
package/dist/cli.js CHANGED
@@ -131,13 +131,60 @@ import { fromMarkdown } from "mdast-util-from-markdown";
131
131
  import { toString } from "mdast-util-to-string";
132
132
  import grayMatter from "gray-matter";
133
133
 
134
+ // src/core/js-frontmatter.ts
135
+ import { createRequire } from "module";
136
+ var MAX_DEPTH = 64;
137
+ var json5;
138
+ function loadJson5() {
139
+ json5 ??= createRequire(import.meta.url)("json5");
140
+ return json5;
141
+ }
142
+ function invalid(reason) {
143
+ return new Error(
144
+ `Invalid JavaScript frontmatter (---js): ${reason}. Only a static object literal is allowed (strings, numbers, booleans, null, arrays, objects). Use YAML frontmatter for anything else.`
145
+ );
146
+ }
147
+ function parseStaticJsFrontmatter(block) {
148
+ let root;
149
+ try {
150
+ root = loadJson5().parse(block);
151
+ } catch (error) {
152
+ throw invalid(error instanceof Error ? error.message : "parse failed");
153
+ }
154
+ if (root === null || typeof root !== "object" || Array.isArray(root)) {
155
+ throw invalid("the top level must be an object");
156
+ }
157
+ const pending = [
158
+ { value: root, depth: 1 }
159
+ ];
160
+ for (let next = pending.pop(); next; next = pending.pop()) {
161
+ const { value, depth } = next;
162
+ if (typeof value === "number" && !Number.isFinite(value)) {
163
+ throw invalid("Infinity and NaN are not allowed");
164
+ }
165
+ if (value === null || typeof value !== "object") continue;
166
+ if (depth > MAX_DEPTH) {
167
+ throw invalid(`nesting is limited to ${MAX_DEPTH} levels`);
168
+ }
169
+ for (const [key, child] of Object.entries(value)) {
170
+ if (key === "__proto__") throw invalid("the __proto__ key is not allowed");
171
+ pending.push({ value: child, depth: depth + 1 });
172
+ }
173
+ }
174
+ return root;
175
+ }
176
+
134
177
  // src/core/null-proto-map.ts
135
178
  function nullProtoMap() {
136
179
  return /* @__PURE__ */ Object.create(null);
137
180
  }
138
181
 
139
182
  // src/core/parser.ts
140
- var GRAY_MATTER_OPTIONS = Object.freeze({});
183
+ var GRAY_MATTER_OPTIONS = Object.freeze({
184
+ engines: {
185
+ javascript: parseStaticJsFrontmatter
186
+ }
187
+ });
141
188
  function frontmatterOffset(content) {
142
189
  return content.length - grayMatter(content, GRAY_MATTER_OPTIONS).content.length;
143
190
  }
@@ -2197,6 +2244,7 @@ function frontmatterInsertEdit(content, key, value) {
2197
2244
  const fmEnd = frontmatterOffset(content);
2198
2245
  if (fmEnd === 0) return null;
2199
2246
  const fmBlock = content.slice(0, fmEnd);
2247
+ if (!/^\uFEFF?---[ \t]*\r?\n/.test(fmBlock)) return null;
2200
2248
  const closeMatch = /\r?\n(---[ \t]*\r?\n)$/.exec(fmBlock);
2201
2249
  if (!closeMatch) return null;
2202
2250
  const fenceLine = closeMatch[1];