accept-md-runtime 2.0.0 → 3.0.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/dist/handler.d.ts CHANGED
@@ -2,12 +2,20 @@
2
2
  * Handler logic: fetch page HTML and return markdown. Used by generated route/API.
3
3
  */
4
4
  import type { NextMarkdownConfig } from './types.js';
5
+ /**
6
+ * Cache entry with expiration and build ID tracking.
7
+ */
8
+ export interface CacheEntry {
9
+ markdown: string;
10
+ expiresAt?: number;
11
+ buildId?: string;
12
+ }
5
13
  export interface GetMarkdownOptions {
6
14
  pathname: string;
7
15
  baseUrl: string;
8
16
  config: NextMarkdownConfig;
9
- /** In-memory cache (pathname -> markdown). Caller can pass a Map for caching. */
10
- cache?: Map<string, string>;
17
+ /** In-memory cache (pathname -> CacheEntry or string for backward compatibility). Caller can pass a Map for caching. */
18
+ cache?: Map<string, CacheEntry | string>;
11
19
  /** Optional headers to forward to the internal fetch (e.g., for Vercel deployment protection) */
12
20
  headers?: HeadersInit;
13
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA8BrD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,iFAAiF;IACjF,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,iGAAiG;IACjG,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+FrF"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA8BrD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,wHAAwH;IACxH,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,CAAC;IACzC,iGAAiG;IACjG,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAuCD;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyIrF"}
package/dist/handler.js CHANGED
@@ -33,6 +33,39 @@ function shouldExclude(pathname, config) {
33
33
  return true;
34
34
  return false;
35
35
  }
36
+ /**
37
+ * Extract revalidation time from Next.js response headers.
38
+ */
39
+ function extractRevalidationTime(res) {
40
+ // Check x-next-revalidate header (seconds)
41
+ const nextRevalidate = res.headers.get('x-next-revalidate');
42
+ if (nextRevalidate) {
43
+ const seconds = parseInt(nextRevalidate, 10);
44
+ if (!isNaN(seconds) && seconds > 0) {
45
+ return seconds;
46
+ }
47
+ }
48
+ // Check Cache-Control header for s-maxage or revalidate
49
+ const cacheControl = res.headers.get('cache-control');
50
+ if (cacheControl) {
51
+ // Match s-maxage=3600 or revalidate=3600
52
+ const sMaxAgeMatch = cacheControl.match(/s-maxage=(\d+)/i);
53
+ if (sMaxAgeMatch) {
54
+ return parseInt(sMaxAgeMatch[1], 10);
55
+ }
56
+ const revalidateMatch = cacheControl.match(/revalidate=(\d+)/i);
57
+ if (revalidateMatch) {
58
+ return parseInt(revalidateMatch[1], 10);
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+ /**
64
+ * Calculate byte size of a string (UTF-8 encoding).
65
+ */
66
+ function getByteSize(str) {
67
+ return new TextEncoder().encode(str).length;
68
+ }
36
69
  /**
37
70
  * Fetch the page at baseUrl + pathname (as HTML), convert to markdown, optionally cache.
38
71
  */
@@ -43,8 +76,31 @@ export async function getMarkdownForPath(options) {
43
76
  throw new Error(`Path excluded from markdown: ${normalizedPath}`);
44
77
  }
45
78
  const cacheKey = normalizedPath;
79
+ // Check cache with expiration and build ID validation
46
80
  if (config.cache !== false && cache?.has(cacheKey)) {
47
- return cache.get(cacheKey);
81
+ const cached = cache.get(cacheKey);
82
+ const currentBuildId = typeof process !== 'undefined' ? process.env.BUILD_ID : undefined;
83
+ // Backward compatibility: handle both CacheEntry and string (old format)
84
+ let entry;
85
+ if (typeof cached === 'string') {
86
+ // Old format: just a string
87
+ return cached;
88
+ }
89
+ else {
90
+ entry = cached;
91
+ }
92
+ // Invalidate if build changed
93
+ if (entry.buildId && entry.buildId !== currentBuildId) {
94
+ cache.delete(cacheKey);
95
+ }
96
+ else if (entry.expiresAt && Date.now() > entry.expiresAt) {
97
+ // Invalidate if expired
98
+ cache.delete(cacheKey);
99
+ }
100
+ else {
101
+ // Cache hit - return cached markdown
102
+ return entry.markdown;
103
+ }
48
104
  }
49
105
  // Prefer the public/base URL first; only fall back to VERCEL_URL when needed.
50
106
  const primaryOrigin = baseUrl.replace(/\/$/, '');
@@ -117,12 +173,26 @@ export async function getMarkdownForPath(options) {
117
173
  throw new Error(`Failed to fetch page: ${message}`);
118
174
  }
119
175
  const html = await res.text();
176
+ // Extract revalidation time from response headers
177
+ const revalidateSeconds = extractRevalidationTime(res);
178
+ const expiresAt = revalidateSeconds ? Date.now() + revalidateSeconds * 1000 : undefined;
179
+ const buildId = typeof process !== 'undefined' ? process.env.BUILD_ID : undefined;
180
+ // Calculate sizes for debug mode
181
+ const htmlSize = getByteSize(html);
120
182
  const md = htmlToMarkdown(html, {
121
183
  cleanSelectors: config.cleanSelectors,
122
184
  transformers: config.transformers,
185
+ debug: config.debug,
186
+ htmlSize: config.debug ? htmlSize : undefined,
123
187
  });
188
+ // Store in cache with expiration and build ID
124
189
  if (config.cache !== false && cache) {
125
- cache.set(cacheKey, md);
190
+ const entry = {
191
+ markdown: md,
192
+ buildId,
193
+ expiresAt,
194
+ };
195
+ cache.set(cacheKey, entry);
126
196
  }
127
197
  return md;
128
198
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,5 +5,5 @@ export { getMarkdownForPath } from './handler.js';
5
5
  export type { GetMarkdownOptions } from './handler.js';
6
6
  export type { NextMarkdownConfig } from './types.js';
7
7
  export { loadConfig } from './config.js';
8
- export { MIDDLEWARE_TEMPLATE, APP_ROUTE_HANDLER_TEMPLATE, PAGES_API_HANDLER_TEMPLATE } from './templates.js';
8
+ export { MIDDLEWARE_TEMPLATE, APP_ROUTE_HANDLER_TEMPLATE, PAGES_API_HANDLER_TEMPLATE, getNextConfigRewrite, } from './templates.js';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -2,5 +2,5 @@
2
2
  export { htmlToMarkdown } from './markdown.js';
3
3
  export { getMarkdownForPath } from './handler.js';
4
4
  export { loadConfig } from './config.js';
5
- export { MIDDLEWARE_TEMPLATE, APP_ROUTE_HANDLER_TEMPLATE, PAGES_API_HANDLER_TEMPLATE } from './templates.js';
5
+ export { MIDDLEWARE_TEMPLATE, APP_ROUTE_HANDLER_TEMPLATE, PAGES_API_HANDLER_TEMPLATE, getNextConfigRewrite, } from './templates.js';
6
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,gBAAgB,CAAC"}
@@ -7,9 +7,12 @@ export interface MarkdownOptions {
7
7
  codeBlockStyle?: 'indented' | 'fenced';
8
8
  /** Custom transformers applied after conversion (md -> md) */
9
9
  transformers?: Array<(md: string) => string>;
10
+ /** Include YAML frontmatter with extracted meta tags (default: true) */
11
+ includeFrontmatter?: boolean;
12
+ /** Enable debug mode to include size information in output (default: false) */
13
+ debug?: boolean;
14
+ /** HTML size in bytes (for debug mode). If not provided, will be calculated. */
15
+ htmlSize?: number;
10
16
  }
11
- /**
12
- * Convert HTML to Markdown. Preserves headings, images, links, tables; strips scripts/styles.
13
- */
14
17
  export declare function htmlToMarkdown(html: string, options?: MarkdownOptions): string;
15
18
  //# sourceMappingURL=markdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAChC,cAAc,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACvC,8DAA8D;IAC9D,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;CAC9C;AAiBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAwBlF"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAChC,cAAc,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACvC,8DAA8D;IAC9D,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAC7C,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA+UD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CA8DlF"}
package/dist/markdown.js CHANGED
@@ -3,6 +3,227 @@
3
3
  */
4
4
  import TurndownService from 'turndown';
5
5
  import { parseHTML } from 'linkedom';
6
+ /**
7
+ * Extract meta tags and JSON-LD scripts from HTML in a single pass for performance.
8
+ * Returns both metadata and JSON-LD scripts.
9
+ */
10
+ function extractMetadataAndJsonLd(html) {
11
+ const { document } = parseHTML(html);
12
+ const metadata = {};
13
+ const jsonLdScripts = [];
14
+ // Extract title
15
+ const titleEl = document.querySelector('title');
16
+ if (titleEl?.textContent) {
17
+ metadata.title = titleEl.textContent.trim();
18
+ }
19
+ // Extract language from html lang attribute
20
+ const htmlEl = document.documentElement;
21
+ const lang = htmlEl.getAttribute('lang');
22
+ if (lang) {
23
+ metadata.language = lang;
24
+ }
25
+ else {
26
+ metadata.language = 'en'; // fallback
27
+ }
28
+ // Extract canonical link
29
+ const canonicalLink = document.querySelector('link[rel="canonical"]');
30
+ if (canonicalLink) {
31
+ const href = canonicalLink.getAttribute('href');
32
+ if (href) {
33
+ metadata.canonical = href;
34
+ }
35
+ }
36
+ // Extract JSON-LD scripts
37
+ document.querySelectorAll('script[type="application/ld+json"]').forEach((script) => {
38
+ const content = script.textContent?.trim();
39
+ if (content) {
40
+ try {
41
+ const parsed = JSON.parse(content);
42
+ jsonLdScripts.push(JSON.stringify(parsed, null, 2));
43
+ }
44
+ catch {
45
+ // Invalid JSON, skip it
46
+ }
47
+ }
48
+ });
49
+ // Extract all meta tags
50
+ document.querySelectorAll('meta').forEach((meta) => {
51
+ const name = meta.getAttribute('name');
52
+ const property = meta.getAttribute('property');
53
+ const content = meta.getAttribute('content');
54
+ if (!content)
55
+ return;
56
+ // Basic meta tags (name attribute)
57
+ if (name) {
58
+ const nameLower = name.toLowerCase();
59
+ switch (nameLower) {
60
+ case 'description':
61
+ metadata.description = content;
62
+ break;
63
+ case 'keywords':
64
+ // Split comma-separated keywords into array
65
+ metadata.keywords = content.split(',').map((k) => k.trim()).filter(Boolean);
66
+ break;
67
+ case 'author':
68
+ metadata.author = content;
69
+ break;
70
+ case 'robots': {
71
+ // Parse robots directive (e.g., "index, follow" or "noindex, nofollow")
72
+ const robots = content.toLowerCase();
73
+ metadata.robots_index = !robots.includes('noindex');
74
+ metadata.robots_follow = !robots.includes('nofollow');
75
+ break;
76
+ }
77
+ default:
78
+ // Twitter card meta tags
79
+ if (name.startsWith('twitter:')) {
80
+ const field = name.replace('twitter:', '');
81
+ switch (field) {
82
+ case 'card':
83
+ metadata.twitter_card = content;
84
+ break;
85
+ case 'title':
86
+ metadata.twitter_title = content;
87
+ break;
88
+ case 'description':
89
+ metadata.twitter_description = content;
90
+ break;
91
+ case 'image':
92
+ metadata.twitter_image = content;
93
+ break;
94
+ case 'creator':
95
+ metadata.twitter_creator = content;
96
+ break;
97
+ case 'site':
98
+ metadata.twitter_site = content;
99
+ break;
100
+ }
101
+ }
102
+ break;
103
+ }
104
+ }
105
+ // OpenGraph meta tags (property attribute)
106
+ if (property && property.startsWith('og:')) {
107
+ const field = property.replace('og:', '');
108
+ switch (field) {
109
+ case 'title':
110
+ metadata.og_title = content;
111
+ break;
112
+ case 'description':
113
+ metadata.og_description = content;
114
+ break;
115
+ case 'type':
116
+ metadata.og_type = content;
117
+ break;
118
+ case 'url':
119
+ metadata.og_url = content;
120
+ break;
121
+ case 'image':
122
+ metadata.og_image = content;
123
+ break;
124
+ case 'site_name':
125
+ metadata.og_site_name = content;
126
+ break;
127
+ case 'locale':
128
+ metadata.og_locale = content;
129
+ break;
130
+ }
131
+ }
132
+ // Article meta tags (property attribute)
133
+ if (property && property.startsWith('article:')) {
134
+ const field = property.replace('article:', 'article_');
135
+ switch (field) {
136
+ case 'article_author':
137
+ metadata.article_author = content;
138
+ break;
139
+ case 'article_published_time':
140
+ metadata.article_published_time = content;
141
+ break;
142
+ case 'article_modified_time':
143
+ metadata.article_modified_time = content;
144
+ break;
145
+ case 'article_section':
146
+ metadata.article_section = content;
147
+ break;
148
+ case 'article_tag':
149
+ // Article tags can be multiple, collect them
150
+ if (!metadata.article_tag) {
151
+ metadata.article_tag = [];
152
+ }
153
+ metadata.article_tag.push(content);
154
+ break;
155
+ }
156
+ }
157
+ });
158
+ return { metadata, jsonLdScripts };
159
+ }
160
+ /**
161
+ * Escape a string for YAML by quoting it.
162
+ */
163
+ function escapeYamlString(value) {
164
+ // Always quote strings for consistency and to handle special characters
165
+ // Escape backslashes and quotes for YAML
166
+ const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
167
+ return `"${escaped}"`;
168
+ }
169
+ /**
170
+ * Format metadata as YAML frontmatter.
171
+ */
172
+ function formatYamlFrontmatter(metadata) {
173
+ const lines = ['---'];
174
+ // Helper to add a line if value exists
175
+ const addLine = (key, value) => {
176
+ if (value === undefined || value === null)
177
+ return;
178
+ if (typeof value === 'boolean') {
179
+ lines.push(`${key}: ${value}`);
180
+ }
181
+ else if (Array.isArray(value)) {
182
+ if (value.length > 0) {
183
+ lines.push(`${key}:`);
184
+ for (const item of value) {
185
+ lines.push(` - ${escapeYamlString(String(item))}`);
186
+ }
187
+ }
188
+ }
189
+ else if (typeof value === 'string' && value.trim() !== '') {
190
+ lines.push(`${key}: ${escapeYamlString(value)}`);
191
+ }
192
+ };
193
+ // Add fields in a logical order
194
+ addLine('title', metadata.title);
195
+ addLine('description', metadata.description);
196
+ addLine('keywords', metadata.keywords);
197
+ addLine('author', metadata.author);
198
+ addLine('canonical', metadata.canonical);
199
+ addLine('language', metadata.language);
200
+ // OpenGraph
201
+ addLine('og_title', metadata.og_title);
202
+ addLine('og_description', metadata.og_description);
203
+ addLine('og_type', metadata.og_type);
204
+ addLine('og_url', metadata.og_url);
205
+ addLine('og_image', metadata.og_image);
206
+ addLine('og_site_name', metadata.og_site_name);
207
+ addLine('og_locale', metadata.og_locale);
208
+ // Article
209
+ addLine('article_author', metadata.article_author);
210
+ addLine('article_published_time', metadata.article_published_time);
211
+ addLine('article_modified_time', metadata.article_modified_time);
212
+ addLine('article_section', metadata.article_section);
213
+ addLine('article_tag', metadata.article_tag);
214
+ // Twitter
215
+ addLine('twitter_card', metadata.twitter_card);
216
+ addLine('twitter_title', metadata.twitter_title);
217
+ addLine('twitter_description', metadata.twitter_description);
218
+ addLine('twitter_image', metadata.twitter_image);
219
+ addLine('twitter_creator', metadata.twitter_creator);
220
+ addLine('twitter_site', metadata.twitter_site);
221
+ // Robots
222
+ addLine('robots_index', metadata.robots_index);
223
+ addLine('robots_follow', metadata.robots_follow);
224
+ lines.push('---');
225
+ return lines.join('\n') + '\n\n';
226
+ }
6
227
  /**
7
228
  * Parse HTML in Node (linkedom) and optionally remove nodes by selector before conversion.
8
229
  */
@@ -20,9 +241,53 @@ function cleanHtml(html, selectors) {
20
241
  }
21
242
  /**
22
243
  * Convert HTML to Markdown. Preserves headings, images, links, tables; strips scripts/styles.
244
+ * Extracts and includes meta tags as YAML frontmatter and JSON-LD structured data as formatted JSON code blocks.
245
+ *
246
+ * @param html - The HTML string to convert to Markdown
247
+ * @param options - Conversion options
248
+ * @returns The converted Markdown string with optional YAML frontmatter
249
+ *
250
+ * @example
251
+ * ```typescript
252
+ * const html = `
253
+ * <html lang="en">
254
+ * <head>
255
+ * <title>My Page</title>
256
+ * <meta name="description" content="Page description" />
257
+ * <meta property="og:title" content="OG Title" />
258
+ * </head>
259
+ * <body><h1>Content</h1></body>
260
+ * </html>
261
+ * `;
262
+ * const markdown = htmlToMarkdown(html);
263
+ * // Returns:
264
+ * // ---
265
+ * // title: "My Page"
266
+ * // description: "Page description"
267
+ * // language: "en"
268
+ * // og_title: "OG Title"
269
+ * // ---
270
+ * //
271
+ * // # Content
272
+ * ```
273
+ *
274
+ * @example
275
+ * ```typescript
276
+ * // Disable frontmatter
277
+ * const markdown = htmlToMarkdown(html, { includeFrontmatter: false });
278
+ * // Returns just the markdown content without frontmatter
279
+ * ```
23
280
  */
281
+ /**
282
+ * Calculate byte size of a string (UTF-8 encoding).
283
+ */
284
+ function getByteSize(str) {
285
+ return new TextEncoder().encode(str).length;
286
+ }
24
287
  export function htmlToMarkdown(html, options = {}) {
25
- const { cleanSelectors = ['nav', 'footer', '.no-markdown', '[data-no-markdown]', 'script', 'style'], headingStyle = 'atx', codeBlockStyle = 'fenced', transformers = [], } = options;
288
+ const { cleanSelectors = ['nav', 'footer', '.no-markdown', '[data-no-markdown]', 'script', 'style'], headingStyle = 'atx', codeBlockStyle = 'fenced', transformers = [], includeFrontmatter = true, debug = false, htmlSize, } = options;
289
+ // Single-pass extraction: get both metadata and JSON-LD scripts in one parse
290
+ const { metadata, jsonLdScripts } = extractMetadataAndJsonLd(html);
26
291
  const cleaned = cleanHtml(html, cleanSelectors);
27
292
  const service = new TurndownService({
28
293
  headingStyle,
@@ -36,6 +301,33 @@ export function htmlToMarkdown(html, options = {}) {
36
301
  for (const fn of transformers) {
37
302
  md = fn(md);
38
303
  }
39
- return md.trim();
304
+ // Prepend YAML frontmatter if enabled and we have any metadata
305
+ let result = '';
306
+ if (includeFrontmatter) {
307
+ const hasMetadata = Object.keys(metadata).some((key) => {
308
+ const value = metadata[key];
309
+ return value !== undefined && value !== null && value !== '';
310
+ });
311
+ if (hasMetadata) {
312
+ result = formatYamlFrontmatter(metadata);
313
+ }
314
+ }
315
+ result += md;
316
+ // Add debug comment with size information if debug mode is enabled
317
+ if (debug) {
318
+ const htmlBytes = htmlSize ?? getByteSize(html);
319
+ const markdownBytes = getByteSize(result);
320
+ const reduction = htmlBytes > 0 ? Math.round(((htmlBytes - markdownBytes) / htmlBytes) * 100) : 0;
321
+ const debugComment = `<!-- accept-md: html_size=${htmlBytes} bytes, markdown_size=${markdownBytes} bytes, reduction=${reduction}% -->\n\n`;
322
+ result = debugComment + result;
323
+ }
324
+ // Append JSON-LD structured data as code blocks
325
+ if (jsonLdScripts.length > 0) {
326
+ result += '\n\n## Structured Data (JSON-LD)\n\n';
327
+ for (const jsonLd of jsonLdScripts) {
328
+ result += '```json\n' + jsonLd + '\n```\n\n';
329
+ }
330
+ }
331
+ return result.trim();
40
332
  }
41
333
  //# sourceMappingURL=markdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,eAAe,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAUrC;;GAEG;AACH,SAAS,SAAS,CAAC,IAAY,EAAE,SAAmB;IAClD,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,UAA2B,EAAE;IACxE,MAAM,EACJ,cAAc,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,OAAO,CAAC,EAC3F,YAAY,GAAG,KAAK,EACpB,cAAc,GAAG,QAAQ,EACzB,YAAY,GAAG,EAAE,GAClB,GAAG,OAAO,CAAC;IAEZ,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC;QAClC,YAAY;QACZ,cAAc;QACd,gBAAgB,EAAE,GAAG;QACrB,SAAS,EAAE,SAAS;KACrB,CAAC,CAAC;IAEH,qFAAqF;IACrF,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;IAEhD,IAAI,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;QAC9B,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IACD,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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"}
@@ -3,5 +3,18 @@
3
3
  */
4
4
  export declare const MIDDLEWARE_TEMPLATE = "// Generated by accept-md. Do not edit the markdown block by hand.\nimport { NextResponse } from 'next/server';\n\nconst MARKDOWN_ACCEPT = new RegExp('\\\\btext/markdown\\\\b', 'i');\nconst EXCLUDED_PREFIXES = ['/api/', '/_next/'];\nconst MARKDOWN_HANDLER_PATH = '/api/accept-md';\n\n/** @param {import('next/server').NextRequest} request */\nexport function middleware(request) {\n const pathname = request.nextUrl.pathname;\n const accept = (request.headers.get('accept') || '').toLowerCase();\n if (!MARKDOWN_ACCEPT.test(accept)) return NextResponse.next();\n if (EXCLUDED_PREFIXES.some((p) => pathname.startsWith(p))) return NextResponse.next();\n\n const url = request.nextUrl.clone();\n url.pathname = MARKDOWN_HANDLER_PATH;\n url.searchParams.set('path', pathname);\n // Let Vercel/Next.js forward all original request metadata (auth, cookies, protection)\n // and only use the query parameter to communicate the original pathname.\n return NextResponse.rewrite(url);\n}\n";
5
5
  export declare const APP_ROUTE_HANDLER_TEMPLATE = "// Generated by accept-md. Do not edit the markdown block by hand.\nimport { NextResponse } from 'next/server';\nimport { getMarkdownForPath, loadConfig } from 'accept-md-runtime';\n\nconst cache = new Map();\nconst HANDLER_PATH = '/api/accept-md';\n\n/** @param {import('next/server').NextRequest} request */\nexport async function GET(request) {\n const pathFromHeader = request.headers.get('x-accept-md-path');\n const pathFromQuery = request.nextUrl.searchParams.get('path');\n const pathname = request.nextUrl.pathname;\n const path = pathFromHeader ?? pathFromQuery ?? (pathname !== HANDLER_PATH ? pathname : null) ?? '/';\n const config = loadConfig(process.cwd());\n const baseUrl = config.baseUrl || request.nextUrl.origin;\n try {\n const markdown = await getMarkdownForPath({\n pathname: path,\n baseUrl,\n config,\n cache: config.cache !== false ? cache : undefined,\n headers: request.headers,\n });\n return new NextResponse(markdown, {\n headers: {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'Cache-Control': config.cache ? 'public, s-maxage=60, stale-while-revalidate' : 'no-store',\n },\n });\n } catch (err) {\n return NextResponse.json(\n { error: err instanceof Error ? err.message : 'Markdown generation failed' },\n { status: 500 }\n );\n }\n}\n";
6
- export declare const PAGES_API_HANDLER_TEMPLATE = "// Generated by accept-md. Do not edit the markdown block by hand.\nimport { getMarkdownForPath, loadConfig } from 'accept-md-runtime';\n\nconst cache = new Map();\n\n/** @param {import('next').NextApiRequest} req @param {import('next').NextApiResponse} res */\nexport default async function handler(req, res) {\n if (req.method !== 'GET') {\n res.setHeader('Allow', 'GET');\n return res.status(405).end();\n }\n const pathFromHeader = req.headers['x-accept-md-path'];\n const pathFromQuery = Array.isArray(req.query.path) ? req.query.path[0] : req.query.path;\n const pathRaw = (pathFromHeader || pathFromQuery) || '/';\n const path = typeof pathRaw === 'string' ? pathRaw : (pathRaw[0] || '/');\n const config = loadConfig(process.cwd());\n const baseUrl = config.baseUrl || (req.headers.origin || req.headers.referer || '').replace(/\\\\/?$/, '') || ('http://localhost:' + (process.env.PORT || 3000));\n // Convert req.headers to Headers for forwarding (e.g., for Vercel deployment protection)\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers.set(key, Array.isArray(value) ? value[0] : value);\n }\n }\n try {\n const markdown = await getMarkdownForPath({\n pathname: path,\n baseUrl,\n config,\n cache: config.cache !== false ? cache : undefined,\n headers,\n });\n res.setHeader('Content-Type', 'text/markdown; charset=utf-8');\n if (config.cache) {\n res.setHeader('Cache-Control', 'public, s-maxage=60, stale-while-revalidate');\n }\n res.status(200).send(markdown);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : 'Markdown generation failed',\n });\n }\n}\n";
6
+ export declare const PAGES_API_HANDLER_TEMPLATE = "// Generated by accept-md. Do not edit the markdown block by hand.\nimport { getMarkdownForPath, loadConfig } from 'accept-md-runtime';\n\nconst cache = new Map();\n\n/** @param {import('next').NextApiRequest} req @param {import('next').NextApiResponse} res */\nexport default async function handler(req, res) {\n if (req.method !== 'GET') {\n res.setHeader('Allow', 'GET');\n return res.status(405).end();\n }\n const pathFromHeader = req.headers['x-accept-md-path'];\n const pathFromQuery = Array.isArray(req.query.path) ? req.query.path[0] : req.query.path;\n const pathRaw = (pathFromHeader || pathFromQuery) || '/';\n const path = typeof pathRaw === 'string' ? pathRaw : (pathRaw[0] || '/');\n const config = loadConfig(process.cwd());\n // Construct baseUrl reliably on Vercel: use host header with protocol, fall back to origin/referer, then VERCEL_URL, then localhost\n let baseUrl = config.baseUrl;\n if (!baseUrl) {\n const host = req.headers.host;\n if (host) {\n const protocol = req.headers['x-forwarded-proto'] || (process.env.VERCEL_URL ? 'https' : 'http');\n baseUrl = protocol + '://' + host;\n } else {\n const originOrReferer = (req.headers.origin || req.headers.referer || '').replace(/\\\\/?$/, '');\n if (originOrReferer) {\n baseUrl = originOrReferer;\n } else if (process.env.VERCEL_URL) {\n baseUrl = process.env.VERCEL_URL.startsWith('http') ? process.env.VERCEL_URL : 'https://' + process.env.VERCEL_URL;\n } else {\n baseUrl = 'http://localhost:' + (process.env.PORT || 3000);\n }\n }\n }\n // Convert req.headers to Headers for forwarding (e.g., for Vercel deployment protection)\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers.set(key, Array.isArray(value) ? value[0] : value);\n }\n }\n try {\n const markdown = await getMarkdownForPath({\n pathname: path,\n baseUrl,\n config,\n cache: config.cache !== false ? cache : undefined,\n headers,\n });\n res.setHeader('Content-Type', 'text/markdown; charset=utf-8');\n if (config.cache) {\n res.setHeader('Cache-Control', 'public, s-maxage=60, stale-while-revalidate');\n }\n res.status(200).send(markdown);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : 'Markdown generation failed',\n });\n }\n}\n";
7
+ /**
8
+ * Returns the rewrite configuration object for next.config.js/ts
9
+ * This is the preferred method over middleware (Next.js is moving away from middleware).
10
+ */
11
+ export declare function getNextConfigRewrite(): {
12
+ source: string;
13
+ destination: string;
14
+ has: {
15
+ type: string;
16
+ key: string;
17
+ value: string;
18
+ }[];
19
+ };
7
20
  //# sourceMappingURL=templates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,mBAAmB,k+BAqB/B,CAAC;AAEF,eAAO,MAAM,0BAA0B,u1CAoCtC,CAAC;AAEF,eAAO,MAAM,0BAA0B,4uDA2CtC,CAAC"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,mBAAmB,k+BAqB/B,CAAC;AAEF,eAAO,MAAM,0BAA0B,u1CAoCtC,CAAC;AAEF,eAAO,MAAM,0BAA0B,u5EA4DtC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB;;;;;;;;EAYnC"}
package/dist/templates.js CHANGED
@@ -76,7 +76,24 @@ export default async function handler(req, res) {
76
76
  const pathRaw = (pathFromHeader || pathFromQuery) || '/';
77
77
  const path = typeof pathRaw === 'string' ? pathRaw : (pathRaw[0] || '/');
78
78
  const config = loadConfig(process.cwd());
79
- const baseUrl = config.baseUrl || (req.headers.origin || req.headers.referer || '').replace(/\\\\/?$/, '') || ('http://localhost:' + (process.env.PORT || 3000));
79
+ // Construct baseUrl reliably on Vercel: use host header with protocol, fall back to origin/referer, then VERCEL_URL, then localhost
80
+ let baseUrl = config.baseUrl;
81
+ if (!baseUrl) {
82
+ const host = req.headers.host;
83
+ if (host) {
84
+ const protocol = req.headers['x-forwarded-proto'] || (process.env.VERCEL_URL ? 'https' : 'http');
85
+ baseUrl = protocol + '://' + host;
86
+ } else {
87
+ const originOrReferer = (req.headers.origin || req.headers.referer || '').replace(/\\\\/?$/, '');
88
+ if (originOrReferer) {
89
+ baseUrl = originOrReferer;
90
+ } else if (process.env.VERCEL_URL) {
91
+ baseUrl = process.env.VERCEL_URL.startsWith('http') ? process.env.VERCEL_URL : 'https://' + process.env.VERCEL_URL;
92
+ } else {
93
+ baseUrl = 'http://localhost:' + (process.env.PORT || 3000);
94
+ }
95
+ }
96
+ }
80
97
  // Convert req.headers to Headers for forwarding (e.g., for Vercel deployment protection)
81
98
  const headers = new Headers();
82
99
  for (const [key, value] of Object.entries(req.headers)) {
@@ -104,4 +121,21 @@ export default async function handler(req, res) {
104
121
  }
105
122
  }
106
123
  `;
124
+ /**
125
+ * Returns the rewrite configuration object for next.config.js/ts
126
+ * This is the preferred method over middleware (Next.js is moving away from middleware).
127
+ */
128
+ export function getNextConfigRewrite() {
129
+ return {
130
+ source: '/:path*',
131
+ destination: '/api/accept-md?path=:path*',
132
+ has: [
133
+ {
134
+ type: 'header',
135
+ key: 'accept',
136
+ value: '(.*)text/markdown(.*)',
137
+ },
138
+ ],
139
+ };
140
+ }
107
141
  //# sourceMappingURL=templates.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBlC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCzC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CzC,CAAC"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBlC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCzC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4DzC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,WAAW,EAAE,4BAA4B;QACzC,GAAG,EAAE;YACH;gBACE,IAAI,EAAE,QAAQ;gBACd,GAAG,EAAE,QAAQ;gBACb,KAAK,EAAE,uBAAuB;aAC/B;SACF;KACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "accept-md-runtime",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "HTML→Markdown conversion and route handler for accept-md (Next.js)",
5
5
  "type": "module",
6
6
  "license": "MIT",