madr-lint 0.4.3 → 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,11 @@
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
+
3
9
  ## 0.4.3
4
10
 
5
11
  ### Patch Changes
package/dist/cli.js CHANGED
@@ -131,6 +131,49 @@ 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);
@@ -139,11 +182,7 @@ function nullProtoMap() {
139
182
  // src/core/parser.ts
140
183
  var GRAY_MATTER_OPTIONS = Object.freeze({
141
184
  engines: {
142
- javascript: () => {
143
- throw new Error(
144
- "JavaScript frontmatter (---js) is not supported. Use YAML frontmatter."
145
- );
146
- }
185
+ javascript: parseStaticJsFrontmatter
147
186
  }
148
187
  });
149
188
  function frontmatterOffset(content) {
@@ -2205,6 +2244,7 @@ function frontmatterInsertEdit(content, key, value) {
2205
2244
  const fmEnd = frontmatterOffset(content);
2206
2245
  if (fmEnd === 0) return null;
2207
2246
  const fmBlock = content.slice(0, fmEnd);
2247
+ if (!/^\uFEFF?---[ \t]*\r?\n/.test(fmBlock)) return null;
2208
2248
  const closeMatch = /\r?\n(---[ \t]*\r?\n)$/.exec(fmBlock);
2209
2249
  if (!closeMatch) return null;
2210
2250
  const fenceLine = closeMatch[1];