gray-matter-es 0.1.2 → 0.1.3

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
@@ -8,6 +8,7 @@ ESM-only [gray-matter](https://github.com/jonschlinkert/gray-matter) implementat
8
8
  ## Features
9
9
 
10
10
  - 🚀 ESM-only, no CommonJS
11
+ - 🌐 Browser-compatible (no Node.js dependencies)
11
12
  - 📦 Zero runtime dependencies (YAML parser bundled from [@std/yaml](https://jsr.io/@std/yaml))
12
13
  - 🔷 Full TypeScript support with strict types
13
14
  - ✅ API compatible with gray-matter
@@ -39,9 +40,6 @@ const str = matter.stringify("content", { title: "Hello" });
39
40
  // ---
40
41
  // content
41
42
 
42
- // Read from file (Node.js)
43
- const fileFromDisk = matter.read("./post.md");
44
-
45
43
  // Test if string has front matter
46
44
  matter.test("---\ntitle: Hello\n---"); // true
47
45
 
@@ -78,11 +76,11 @@ console.log(file.excerpt); // 'excerpt\n'
78
76
 
79
77
  ### `matter(input, options?)`
80
78
 
81
- Parse front matter from a string or buffer.
79
+ Parse front matter from a string or Uint8Array.
82
80
 
83
81
  **Parameters:**
84
82
 
85
- - `input` - String, Buffer, or object with `content` property
83
+ - `input` - String, Uint8Array, or object with `content` property
86
84
  - `options` - Optional configuration
87
85
 
88
86
  **Returns:** `GrayMatterFile` object with:
@@ -90,7 +88,7 @@ Parse front matter from a string or buffer.
90
88
  - `data` - Parsed front matter data
91
89
  - `content` - Content after front matter
92
90
  - `excerpt` - Extracted excerpt (if enabled)
93
- - `orig` - Original input as Buffer
91
+ - `orig` - Original input as Uint8Array
94
92
  - `language` - Detected/specified language
95
93
  - `matter` - Raw front matter string
96
94
  - `isEmpty` - True if front matter block was empty
@@ -100,10 +98,6 @@ Parse front matter from a string or buffer.
100
98
 
101
99
  Stringify data to front matter and append content.
102
100
 
103
- ### `matter.read(filepath, options?)`
104
-
105
- Synchronously read and parse a file.
106
-
107
101
  ### `matter.test(str, options?)`
108
102
 
109
103
  Test if a string has front matter.
@@ -123,7 +117,9 @@ Detect the language specified after the opening delimiter.
123
117
  ## Differences from gray-matter
124
118
 
125
119
  - ESM-only (no CommonJS support)
120
+ - Browser-compatible (no Node.js dependencies)
126
121
  - Uses [`@std/yaml`](https://jsr.io/@std/yaml) instead of `js-yaml`
122
+ - Removed `matter.read()` (use your own file reading)
127
123
  - Removed JavaScript front matter engine (security: avoids `eval`)
128
124
  - Removed deprecated options (`lang`, `delims`, `parsers`)
129
125
  - Removed `section-matter` support
package/dist/index.d.mts CHANGED
@@ -43,8 +43,8 @@ interface GrayMatterFile {
43
43
  content: string;
44
44
  /** The extracted excerpt (if enabled) */
45
45
  excerpt: string;
46
- /** The original input as a Buffer */
47
- orig: Buffer;
46
+ /** The original input as a Uint8Array */
47
+ orig: Uint8Array;
48
48
  /** The detected/specified language */
49
49
  language: string;
50
50
  /** The raw front matter string (without delimiters) */
@@ -53,15 +53,13 @@ interface GrayMatterFile {
53
53
  isEmpty: boolean;
54
54
  /** The original content if isEmpty is true */
55
55
  empty?: string;
56
- /** File path (set by matter.read) */
57
- path?: string;
58
56
  /** Stringify the file back to a string */
59
57
  stringify: (data?: Record<string, unknown>, options?: GrayMatterOptions) => string;
60
58
  }
61
59
  /**
62
60
  * Input that can be passed to gray-matter
63
61
  */
64
- type GrayMatterInput = string | Buffer | {
62
+ type GrayMatterInput = string | Uint8Array | {
65
63
  content: string;
66
64
  data?: Record<string, unknown>;
67
65
  };
@@ -71,7 +69,6 @@ type GrayMatterInput = string | Buffer | {
71
69
  interface MatterFunction {
72
70
  (input: GrayMatterInput, options?: GrayMatterOptions): GrayMatterFile;
73
71
  stringify: (file: GrayMatterFile | string, data?: Record<string, unknown>, options?: GrayMatterOptions) => string;
74
- read: (filepath: string, options?: GrayMatterOptions) => GrayMatterFile;
75
72
  test: (str: string, options?: GrayMatterOptions) => boolean;
76
73
  language: (str: string, options?: GrayMatterOptions) => {
77
74
  raw: string;
package/dist/index.mjs CHANGED
@@ -1,7 +1,6 @@
1
- import { readFileSync } from "node:fs";
2
- import { Buffer } from "node:buffer";
3
-
4
1
  //#region src/utils.ts
2
+ const textEncoder = new TextEncoder();
3
+ const textDecoder = new TextDecoder();
5
4
  /**
6
5
  * Strip BOM (Byte Order Mark) from a string
7
6
  */
@@ -9,29 +8,29 @@ function stripBom(str$1) {
9
8
  return str$1.charCodeAt(0) === 65279 ? str$1.slice(1) : str$1;
10
9
  }
11
10
  /**
12
- * Returns true if `val` is a Buffer
11
+ * Returns true if `val` is a Uint8Array
13
12
  */
14
- function isBuffer(val) {
15
- return Buffer.isBuffer(val);
13
+ function isUint8Array(val) {
14
+ return val instanceof Uint8Array;
16
15
  }
17
16
  /**
18
- * Returns true if `val` is a plain object (not a Buffer or other special object)
17
+ * Returns true if `val` is a plain object (not a Uint8Array or other special object)
19
18
  */
20
19
  function isObject$1(val) {
21
- return typeof val === "object" && val !== null && !Array.isArray(val) && !Buffer.isBuffer(val);
20
+ return typeof val === "object" && val !== null && !Array.isArray(val) && !(val instanceof Uint8Array);
22
21
  }
23
22
  /**
24
- * Cast `input` to a Buffer
23
+ * Cast `input` to a Uint8Array
25
24
  */
26
- function toBuffer(input) {
27
- return typeof input === "string" ? Buffer.from(input) : input;
25
+ function toUint8Array(input) {
26
+ return typeof input === "string" ? textEncoder.encode(input) : input;
28
27
  }
29
28
  /**
30
29
  * Cast `input` to a string, stripping BOM
31
30
  */
32
31
  function toString(input) {
33
- if (isBuffer(input)) return stripBom(String(input));
34
- if (typeof input !== "string") throw new TypeError("expected input to be a string or buffer");
32
+ if (isUint8Array(input)) return stripBom(textDecoder.decode(input));
33
+ if (typeof input !== "string") throw new TypeError("expected input to be a string or Uint8Array");
35
34
  return stripBom(input);
36
35
  }
37
36
  /**
@@ -2271,7 +2270,7 @@ function toFile(input) {
2271
2270
  data,
2272
2271
  content,
2273
2272
  excerpt: "",
2274
- orig: toBuffer(normalized.content ?? ""),
2273
+ orig: toUint8Array(normalized.content ?? ""),
2275
2274
  language,
2276
2275
  matter: matter$1,
2277
2276
  isEmpty: false,
@@ -2384,11 +2383,6 @@ const matter = Object.assign(matterImpl, {
2384
2383
  if (typeof file === "string") file = matterImpl(file, options);
2385
2384
  return stringify(file, data, options);
2386
2385
  },
2387
- read: (filepath, options) => {
2388
- const file = matterImpl(readFileSync(filepath, "utf8"), options);
2389
- file.path = filepath;
2390
- return file;
2391
- },
2392
2386
  test: matterTest,
2393
2387
  language: matterLanguage,
2394
2388
  clearCache: () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gray-matter-es",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "ES-only gray-matter",
5
5
  "keywords": [
6
6
  "esm",
package/src/excerpt.ts CHANGED
@@ -36,13 +36,12 @@ export function excerpt(file: GrayMatterFile, options?: GrayMatterOptions): Gray
36
36
 
37
37
  if (import.meta.vitest) {
38
38
  const { fc, test } = await import("@fast-check/vitest");
39
- const { Buffer } = await import("node:buffer");
40
39
 
41
40
  const makeFile = (content: string, data: Record<string, unknown> = {}): GrayMatterFile => ({
42
41
  content,
43
42
  data,
44
43
  excerpt: "",
45
- orig: Buffer.from(content),
44
+ orig: new TextEncoder().encode(content),
46
45
  language: "yaml",
47
46
  matter: "",
48
47
  isEmpty: false,
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { readFileSync } from "node:fs";
2
1
  import { defaults } from "./defaults.ts";
3
2
  import { toBuiltinLanguage } from "./engines.ts";
4
3
  import { excerpt } from "./excerpt.ts";
@@ -179,16 +178,6 @@ const matter: MatterFunction = Object.assign(matterImpl, {
179
178
  return stringify(file, data, options);
180
179
  },
181
180
 
182
- /**
183
- * Synchronously read a file from the file system and parse front matter.
184
- */
185
- read: (filepath: string, options?: GrayMatterOptions): GrayMatterFile => {
186
- const str = readFileSync(filepath, "utf8");
187
- const file = matterImpl(str, options);
188
- file.path = filepath;
189
- return file;
190
- },
191
-
192
181
  /**
193
182
  * Returns true if the given string has front matter.
194
183
  */
@@ -218,7 +207,6 @@ export default matter;
218
207
 
219
208
  if (import.meta.vitest) {
220
209
  const { fc, test } = await import("@fast-check/vitest");
221
- const { Buffer } = await import("node:buffer");
222
210
 
223
211
  describe("matter", () => {
224
212
  beforeEach(() => {
@@ -356,16 +344,16 @@ if (import.meta.vitest) {
356
344
  const yamlSafeObject = fc.dictionary(yamlKey, yamlSafeValue, { minKeys: 1, maxKeys: 5 });
357
345
 
358
346
  test.prop([fc.string({ minLength: 1, maxLength: 100 })])(
359
- "Buffer and string input should produce equivalent results",
347
+ "Uint8Array and string input should produce equivalent results",
360
348
  (content) => {
361
349
  matter.clearCache();
362
350
  const fromString = matter(content);
363
351
  matter.clearCache();
364
- const fromBuffer = matter(Buffer.from(content));
352
+ const fromUint8Array = matter(new TextEncoder().encode(content));
365
353
 
366
- expect(fromString.content).toBe(fromBuffer.content);
367
- expect(fromString.data).toEqual(fromBuffer.data);
368
- expect(fromString.excerpt).toBe(fromBuffer.excerpt);
354
+ expect(fromString.content).toBe(fromUint8Array.content);
355
+ expect(fromString.data).toEqual(fromUint8Array.data);
356
+ expect(fromString.excerpt).toBe(fromUint8Array.excerpt);
369
357
  },
370
358
  );
371
359
 
package/src/stringify.ts CHANGED
@@ -79,7 +79,7 @@ if (import.meta.vitest) {
79
79
  content: "hello world",
80
80
  data: { title: "Test" },
81
81
  excerpt: "",
82
- orig: Buffer.from(""),
82
+ orig: new Uint8Array(),
83
83
  language: "yaml",
84
84
  matter: "",
85
85
  isEmpty: false,
@@ -104,7 +104,7 @@ if (import.meta.vitest) {
104
104
  content: "no newline",
105
105
  data: { key: "value" },
106
106
  excerpt: "",
107
- orig: Buffer.from(""),
107
+ orig: new Uint8Array(),
108
108
  language: "yaml",
109
109
  matter: "",
110
110
  isEmpty: false,
@@ -119,7 +119,7 @@ if (import.meta.vitest) {
119
119
  content: "content only",
120
120
  data: {},
121
121
  excerpt: "",
122
- orig: Buffer.from(""),
122
+ orig: new Uint8Array(),
123
123
  language: "yaml",
124
124
  matter: "",
125
125
  isEmpty: false,
@@ -134,7 +134,7 @@ if (import.meta.vitest) {
134
134
  content: "main content",
135
135
  data: { title: "Test" },
136
136
  excerpt: "This is excerpt",
137
- orig: Buffer.from(""),
137
+ orig: new Uint8Array(),
138
138
  language: "yaml",
139
139
  matter: "",
140
140
  isEmpty: false,
@@ -155,7 +155,7 @@ if (import.meta.vitest) {
155
155
  content: "test content",
156
156
  data,
157
157
  excerpt: "",
158
- orig: Buffer.from(""),
158
+ orig: new Uint8Array(),
159
159
  language: "yaml",
160
160
  matter: "",
161
161
  isEmpty: false,
@@ -172,14 +172,14 @@ if (import.meta.vitest) {
172
172
  content,
173
173
  data: { key: "value" },
174
174
  excerpt: "",
175
- orig: Buffer.from(""),
175
+ orig: new Uint8Array(),
176
176
  language: "yaml",
177
177
  matter: "",
178
178
  isEmpty: false,
179
179
  stringify: () => "",
180
180
  };
181
181
  const result = stringify(file);
182
- expect(typeof result).toBe("string");
182
+ expect(result).toBeTypeOf("string");
183
183
  expect(result.endsWith("\n")).toBe(true);
184
184
  },
185
185
  );
package/src/to-file.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import type { GrayMatterFile, GrayMatterInput, GrayMatterOptions } from "./types.ts";
2
- import { getStringProp, isObject, toBuffer, toString } from "./utils.ts";
2
+ import { getStringProp, isObject, toUint8Array, toString } from "./utils.ts";
3
3
  import { stringify } from "./stringify.ts";
4
4
 
5
5
  /**
6
6
  * Internal input shape after normalization
7
7
  */
8
8
  interface NormalizedInput {
9
- content: string | Buffer;
9
+ content: string | Uint8Array;
10
10
  data?: unknown;
11
11
  language?: string;
12
12
  matter?: string;
@@ -24,7 +24,7 @@ function normalizeInput(input: GrayMatterInput): NormalizedInput {
24
24
  matter: getStringProp(input, "matter"),
25
25
  };
26
26
  }
27
- // string or Buffer
27
+ // string or Uint8Array
28
28
  return { content: input };
29
29
  }
30
30
 
@@ -38,7 +38,7 @@ export function toFile(input: GrayMatterInput): GrayMatterFile {
38
38
  const content = toString(normalized.content ?? "");
39
39
  const language = normalized.language ?? "";
40
40
  const matter = normalized.matter ?? "";
41
- const orig = toBuffer(normalized.content ?? "");
41
+ const orig = toUint8Array(normalized.content ?? "");
42
42
 
43
43
  const file: GrayMatterFile = {
44
44
  data,
@@ -65,7 +65,6 @@ export function toFile(input: GrayMatterInput): GrayMatterFile {
65
65
 
66
66
  if (import.meta.vitest) {
67
67
  const { fc, test } = await import("@fast-check/vitest");
68
- const { Buffer } = await import("node:buffer");
69
68
 
70
69
  describe("toFile", () => {
71
70
  it("should convert string to file object", () => {
@@ -78,8 +77,8 @@ if (import.meta.vitest) {
78
77
  expect(result.matter).toBe("");
79
78
  });
80
79
 
81
- it("should convert Buffer to file object", () => {
82
- const result = toFile(Buffer.from("buffer content"));
80
+ it("should convert Uint8Array to file object", () => {
81
+ const result = toFile(new TextEncoder().encode("buffer content"));
83
82
  expect(result.content).toBe("buffer content");
84
83
  expect(result.data).toEqual({});
85
84
  });
@@ -90,15 +89,15 @@ if (import.meta.vitest) {
90
89
  expect(result.data).toEqual({ key: "value" });
91
90
  });
92
91
 
93
- it("should preserve orig as Buffer", () => {
92
+ it("should preserve orig as Uint8Array", () => {
94
93
  const result = toFile("test");
95
- expect(Buffer.isBuffer(result.orig)).toBe(true);
96
- expect(result.orig.toString()).toBe("test");
94
+ expect(result.orig).toBeInstanceOf(Uint8Array);
95
+ expect(new TextDecoder().decode(result.orig)).toBe("test");
97
96
  });
98
97
 
99
98
  it("should set stringify as a function", () => {
100
99
  const result = toFile("content");
101
- expect(typeof result.stringify).toBe("function");
100
+ expect(result.stringify).toBeTypeOf("function");
102
101
  });
103
102
 
104
103
  it("should initialize data to empty object if not provided", () => {
@@ -126,25 +125,24 @@ if (import.meta.vitest) {
126
125
  "should always return valid file object for any string",
127
126
  (input) => {
128
127
  const result = toFile(input);
129
- expect(typeof result.content).toBe("string");
130
- expect(typeof result.data).toBe("object");
128
+ expect(result.content).toBeTypeOf("string");
129
+ expect(result.data).toBeTypeOf("object");
131
130
  expect(result.data).not.toBeNull();
132
- expect(typeof result.isEmpty).toBe("boolean");
133
- expect(typeof result.excerpt).toBe("string");
134
- expect(typeof result.language).toBe("string");
135
- expect(typeof result.matter).toBe("string");
136
- expect(Buffer.isBuffer(result.orig)).toBe(true);
137
- expect(typeof result.stringify).toBe("function");
131
+ expect(result.isEmpty).toBeTypeOf("boolean");
132
+ expect(result.excerpt).toBeTypeOf("string");
133
+ expect(result.language).toBeTypeOf("string");
134
+ expect(result.matter).toBeTypeOf("string");
135
+ expect(result.orig).toBeInstanceOf(Uint8Array);
136
+ expect(result.stringify).toBeTypeOf("function");
138
137
  },
139
138
  );
140
139
 
141
140
  test.prop([fc.uint8Array({ minLength: 0, maxLength: 200 })])(
142
- "should handle any Buffer input",
141
+ "should handle any Uint8Array input",
143
142
  (arr) => {
144
- const buffer = Buffer.from(arr);
145
- const result = toFile(buffer);
146
- expect(typeof result.content).toBe("string");
147
- expect(Buffer.isBuffer(result.orig)).toBe(true);
143
+ const result = toFile(arr);
144
+ expect(result.content).toBeTypeOf("string");
145
+ expect(result.orig).toBeInstanceOf(Uint8Array);
148
146
  },
149
147
  );
150
148
 
@@ -159,7 +157,7 @@ if (import.meta.vitest) {
159
157
  const input = data !== undefined ? { content, data } : { content };
160
158
  const result = toFile(input);
161
159
  expect(result.content).toBe(content);
162
- expect(typeof result.data).toBe("object");
160
+ expect(result.data).toBeTypeOf("object");
163
161
  if (data !== undefined) {
164
162
  expect(result.data).toEqual(data);
165
163
  }
package/src/types.ts CHANGED
@@ -45,8 +45,8 @@ export interface GrayMatterFile {
45
45
  content: string;
46
46
  /** The extracted excerpt (if enabled) */
47
47
  excerpt: string;
48
- /** The original input as a Buffer */
49
- orig: Buffer;
48
+ /** The original input as a Uint8Array */
49
+ orig: Uint8Array;
50
50
  /** The detected/specified language */
51
51
  language: string;
52
52
  /** The raw front matter string (without delimiters) */
@@ -55,8 +55,6 @@ export interface GrayMatterFile {
55
55
  isEmpty: boolean;
56
56
  /** The original content if isEmpty is true */
57
57
  empty?: string;
58
- /** File path (set by matter.read) */
59
- path?: string;
60
58
  /** Stringify the file back to a string */
61
59
  stringify: (data?: Record<string, unknown>, options?: GrayMatterOptions) => string;
62
60
  }
@@ -64,7 +62,10 @@ export interface GrayMatterFile {
64
62
  /**
65
63
  * Input that can be passed to gray-matter
66
64
  */
67
- export type GrayMatterInput = string | Buffer | { content: string; data?: Record<string, unknown> };
65
+ export type GrayMatterInput =
66
+ | string
67
+ | Uint8Array
68
+ | { content: string; data?: Record<string, unknown> };
68
69
 
69
70
  /**
70
71
  * The matter function interface with static methods
@@ -76,7 +77,6 @@ export interface MatterFunction {
76
77
  data?: Record<string, unknown>,
77
78
  options?: GrayMatterOptions,
78
79
  ) => string;
79
- read: (filepath: string, options?: GrayMatterOptions) => GrayMatterFile;
80
80
  test: (str: string, options?: GrayMatterOptions) => boolean;
81
81
  language: (str: string, options?: GrayMatterOptions) => { raw: string; name: string };
82
82
  clearCache: () => void;
package/src/utils.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { Buffer } from "node:buffer";
1
+ const textEncoder = new TextEncoder();
2
+ const textDecoder = new TextDecoder();
2
3
 
3
4
  /**
4
5
  * Strip BOM (Byte Order Mark) from a string
@@ -8,33 +9,35 @@ function stripBom(str: string): string {
8
9
  }
9
10
 
10
11
  /**
11
- * Returns true if `val` is a Buffer
12
+ * Returns true if `val` is a Uint8Array
12
13
  */
13
- function isBuffer(val: unknown): val is Buffer {
14
- return Buffer.isBuffer(val);
14
+ function isUint8Array(val: unknown): val is Uint8Array {
15
+ return val instanceof Uint8Array;
15
16
  }
16
17
 
17
18
  /**
18
- * Returns true if `val` is a plain object (not a Buffer or other special object)
19
+ * Returns true if `val` is a plain object (not a Uint8Array or other special object)
19
20
  */
20
21
  export function isObject(val: unknown): val is Record<string, unknown> {
21
- return typeof val === "object" && val !== null && !Array.isArray(val) && !Buffer.isBuffer(val);
22
+ return (
23
+ typeof val === "object" && val !== null && !Array.isArray(val) && !(val instanceof Uint8Array)
24
+ );
22
25
  }
23
26
 
24
27
  /**
25
- * Cast `input` to a Buffer
28
+ * Cast `input` to a Uint8Array
26
29
  */
27
- export function toBuffer(input: string | Buffer): Buffer {
28
- return typeof input === "string" ? Buffer.from(input) : input;
30
+ export function toUint8Array(input: string | Uint8Array): Uint8Array {
31
+ return typeof input === "string" ? textEncoder.encode(input) : input;
29
32
  }
30
33
 
31
34
  /**
32
35
  * Cast `input` to a string, stripping BOM
33
36
  */
34
- export function toString(input: string | Buffer): string {
35
- if (isBuffer(input)) return stripBom(String(input));
37
+ export function toString(input: string | Uint8Array): string {
38
+ if (isUint8Array(input)) return stripBom(textDecoder.decode(input));
36
39
  if (typeof input !== "string") {
37
- throw new TypeError("expected input to be a string or buffer");
40
+ throw new TypeError("expected input to be a string or Uint8Array");
38
41
  }
39
42
  return stripBom(input);
40
43
  }
@@ -111,13 +114,13 @@ if (import.meta.vitest) {
111
114
  });
112
115
  });
113
116
 
114
- describe("isBuffer", () => {
115
- it("should return true for Buffer", () => {
116
- expect(isBuffer(Buffer.from("test"))).toBe(true);
117
+ describe("isUint8Array", () => {
118
+ it("should return true for Uint8Array", () => {
119
+ expect(isUint8Array(new Uint8Array([1, 2, 3]))).toBe(true);
117
120
  });
118
121
 
119
122
  it("should return false for string", () => {
120
- expect(isBuffer("test")).toBe(false);
123
+ expect(isUint8Array("test")).toBe(false);
121
124
  });
122
125
  });
123
126
 
@@ -135,8 +138,8 @@ if (import.meta.vitest) {
135
138
  expect(isObject(null)).toBe(false);
136
139
  });
137
140
 
138
- it("should return false for Buffer", () => {
139
- expect(isObject(Buffer.from("test"))).toBe(false);
141
+ it("should return false for Uint8Array", () => {
142
+ expect(isObject(new Uint8Array([1, 2, 3]))).toBe(false);
140
143
  });
141
144
  });
142
145