@x-wave/blog 2.7.3 → 2.7.5
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/cli/index.js +2 -2
- package/index.js +2 -1
- package/package.json +1 -1
- package/types/frontmatter.d.ts +12 -0
- package/types/frontmatter.d.ts.map +1 -0
- package/types/frontmatter.js +63 -0
- package/types/frontmatter.js.map +1 -0
- package/types/index.d.ts +34 -0
- package/types/index.d.ts.map +1 -0
- package/types/index.js +2 -0
- package/types/index.js.map +1 -0
- package/vite-config/blog-discovery.js +1 -1
- package/types/frontmatter.ts +0 -75
- package/types/index.ts +0 -43
package/cli/index.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* --output Path to the output directory where JSON index files will be written
|
|
14
14
|
*
|
|
15
15
|
* Output structure (one set of files per language):
|
|
16
|
-
* <output>/<lang>/latest.json - Latest
|
|
16
|
+
* <output>/<lang>/latest.json - Latest 50 articles (for the home page)
|
|
17
17
|
* <output>/<lang>/months-index.json - Sorted list of YYYY-MM strings with articles
|
|
18
18
|
* <output>/<lang>/months/<YYYY-MM>.json - Articles for a specific month
|
|
19
19
|
*
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import fs from 'node:fs'
|
|
25
25
|
import path from 'node:path'
|
|
26
26
|
|
|
27
|
-
const LATEST_COUNT =
|
|
27
|
+
const LATEST_COUNT = 50
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Parse CLI arguments from process.argv.
|
package/index.js
CHANGED
|
@@ -69,7 +69,8 @@ function d_(e) {
|
|
|
69
69
|
}
|
|
70
70
|
function Ml(e) {
|
|
71
71
|
const t = e.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
72
|
-
if (!t)
|
|
72
|
+
if (!t)
|
|
73
|
+
return { frontmatter: {}, content: e };
|
|
73
74
|
const r = {}, n = t[1];
|
|
74
75
|
let i = "", a = !1;
|
|
75
76
|
const o = [];
|
package/package.json
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ParsedFrontmatter {
|
|
2
|
+
frontmatter: Record<string, unknown>;
|
|
3
|
+
content: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Parse YAML frontmatter from MDX content.
|
|
7
|
+
* Supports string (with optional double quotes), boolean, and array values.
|
|
8
|
+
*
|
|
9
|
+
* @returns The parsed frontmatter record and the content with frontmatter stripped.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseFrontmatter(rawContent: string): ParsedFrontmatter;
|
|
12
|
+
//# sourceMappingURL=frontmatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,OAAO,EAAE,MAAM,CAAA;CACf;AASD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,CAwDtE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strip optional surrounding double quotes from a string value.
|
|
3
|
+
*/
|
|
4
|
+
function stripQuotes(value) {
|
|
5
|
+
return value.replace(/^"(.*)"$/, '$1');
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Parse YAML frontmatter from MDX content.
|
|
9
|
+
* Supports string (with optional double quotes), boolean, and array values.
|
|
10
|
+
*
|
|
11
|
+
* @returns The parsed frontmatter record and the content with frontmatter stripped.
|
|
12
|
+
*/
|
|
13
|
+
export function parseFrontmatter(rawContent) {
|
|
14
|
+
const match = rawContent.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
15
|
+
if (!match)
|
|
16
|
+
return { frontmatter: {}, content: rawContent };
|
|
17
|
+
const frontmatter = {};
|
|
18
|
+
const frontmatterText = match[1];
|
|
19
|
+
let currentKey = '';
|
|
20
|
+
let isArrayContext = false;
|
|
21
|
+
const arrayValues = [];
|
|
22
|
+
for (const line of frontmatterText.split('\n')) {
|
|
23
|
+
const trimmed = line.trim();
|
|
24
|
+
// Handle array items (lines starting with -)
|
|
25
|
+
if (trimmed.startsWith('-')) {
|
|
26
|
+
if (isArrayContext) {
|
|
27
|
+
arrayValues.push(trimmed.substring(1).trim());
|
|
28
|
+
}
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// If we were in array context and hit a non-array line, save the array
|
|
32
|
+
if (isArrayContext) {
|
|
33
|
+
frontmatter[currentKey] = arrayValues.slice();
|
|
34
|
+
arrayValues.length = 0;
|
|
35
|
+
isArrayContext = false;
|
|
36
|
+
}
|
|
37
|
+
// Handle key-value pairs
|
|
38
|
+
const colonIndex = trimmed.indexOf(':');
|
|
39
|
+
if (colonIndex !== -1) {
|
|
40
|
+
const key = trimmed.substring(0, colonIndex).trim();
|
|
41
|
+
const value = trimmed.substring(colonIndex + 1).trim();
|
|
42
|
+
currentKey = key;
|
|
43
|
+
// Empty value means an array follows on subsequent lines
|
|
44
|
+
if (value === '') {
|
|
45
|
+
isArrayContext = true;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (value === 'true')
|
|
49
|
+
frontmatter[currentKey] = true;
|
|
50
|
+
else if (value === 'false')
|
|
51
|
+
frontmatter[currentKey] = false;
|
|
52
|
+
else
|
|
53
|
+
frontmatter[currentKey] = stripQuotes(value);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Flush trailing array
|
|
57
|
+
if (isArrayContext && arrayValues.length > 0) {
|
|
58
|
+
frontmatter[currentKey] = arrayValues;
|
|
59
|
+
}
|
|
60
|
+
const content = rawContent.replace(/^---\s*\n[\s\S]*?\n---\s*\n/, '');
|
|
61
|
+
return { frontmatter, content };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,SAAS,WAAW,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;IAE/D,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAA;IAE3D,MAAM,WAAW,GAA4B,EAAE,CAAA;IAC/C,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;IAChC,IAAI,UAAU,GAAG,EAAE,CAAA;IACnB,IAAI,cAAc,GAAG,KAAK,CAAA;IAC1B,MAAM,WAAW,GAAa,EAAE,CAAA;IAEhC,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAE3B,6CAA6C;QAC7C,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,cAAc,EAAE,CAAC;gBACpB,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;YAC9C,CAAC;YACD,SAAQ;QACT,CAAC;QAED,uEAAuE;QACvE,IAAI,cAAc,EAAE,CAAC;YACpB,WAAW,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,CAAA;YAC7C,WAAW,CAAC,MAAM,GAAG,CAAC,CAAA;YACtB,cAAc,GAAG,KAAK,CAAA;QACvB,CAAC;QAED,yBAAyB;QACzB,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAA;YACnD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YACtD,UAAU,GAAG,GAAG,CAAA;YAEhB,yDAAyD;YACzD,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;gBAClB,cAAc,GAAG,IAAI,CAAA;gBACrB,SAAQ;YACT,CAAC;YAED,IAAI,KAAK,KAAK,MAAM;gBAAE,WAAW,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA;iBAC/C,IAAI,KAAK,KAAK,OAAO;gBAAE,WAAW,CAAC,UAAU,CAAC,GAAG,KAAK,CAAA;;gBACtD,WAAW,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;QAClD,CAAC;IACF,CAAC;IAED,uBAAuB;IACvB,IAAI,cAAc,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,WAAW,CAAC,UAAU,CAAC,GAAG,WAAW,CAAA;IACtC,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAA;IAErE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAA;AAChC,CAAC"}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type { ParsedFrontmatter } from './frontmatter.js';
|
|
2
|
+
export { parseFrontmatter } from './frontmatter.js';
|
|
3
|
+
export interface NavigationItem {
|
|
4
|
+
slug: string;
|
|
5
|
+
hasAdvanced?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface NavigationItemWithTitle extends NavigationItem {
|
|
8
|
+
title: string;
|
|
9
|
+
}
|
|
10
|
+
export interface NavigationSection {
|
|
11
|
+
title: string;
|
|
12
|
+
items: NavigationItem[];
|
|
13
|
+
defaultOpen?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface NavigationSectionWithTitles {
|
|
16
|
+
title: string;
|
|
17
|
+
items: NavigationItemWithTitle[];
|
|
18
|
+
defaultOpen?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export type NavigationEntry = NavigationSection | NavigationItem;
|
|
21
|
+
export type NavigationEntryWithTitles = NavigationSectionWithTitles | NavigationItemWithTitle;
|
|
22
|
+
export interface LoadedContent {
|
|
23
|
+
content: string;
|
|
24
|
+
frontmatter: {
|
|
25
|
+
title?: string;
|
|
26
|
+
hasAdvanced?: boolean;
|
|
27
|
+
tags?: string[];
|
|
28
|
+
date?: string;
|
|
29
|
+
author?: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export type SupportedLanguage = string;
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAEnD,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC9D,KAAK,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,iBAAiB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,WAAW,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,uBAAuB,EAAE,CAAA;IAChC,WAAW,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,cAAc,CAAA;AAEhE,MAAM,MAAM,yBAAyB,GAClC,2BAA2B,GAC3B,uBAAuB,CAAA;AAE1B,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;QACf,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KACtB,CAAA;CACD;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAA"}
|
package/types/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
|
package/types/frontmatter.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
export interface ParsedFrontmatter {
|
|
2
|
-
frontmatter: Record<string, unknown>
|
|
3
|
-
content: string
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Strip optional surrounding double quotes from a string value.
|
|
8
|
-
*/
|
|
9
|
-
function stripQuotes(value: string): string {
|
|
10
|
-
return value.replace(/^"(.*)"$/, '$1')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Parse YAML frontmatter from MDX content.
|
|
15
|
-
* Supports string (with optional double quotes), boolean, and array values.
|
|
16
|
-
*
|
|
17
|
-
* @returns The parsed frontmatter record and the content with frontmatter stripped.
|
|
18
|
-
*/
|
|
19
|
-
export function parseFrontmatter(rawContent: string): ParsedFrontmatter {
|
|
20
|
-
const match = rawContent.match(/^---\s*\n([\s\S]*?)\n---\s*\n/)
|
|
21
|
-
|
|
22
|
-
if (!match) return { frontmatter: {}, content: rawContent }
|
|
23
|
-
|
|
24
|
-
const frontmatter: Record<string, unknown> = {}
|
|
25
|
-
const frontmatterText = match[1]
|
|
26
|
-
let currentKey = ''
|
|
27
|
-
let isArrayContext = false
|
|
28
|
-
const arrayValues: string[] = []
|
|
29
|
-
|
|
30
|
-
for (const line of frontmatterText.split('\n')) {
|
|
31
|
-
const trimmed = line.trim()
|
|
32
|
-
|
|
33
|
-
// Handle array items (lines starting with -)
|
|
34
|
-
if (trimmed.startsWith('-')) {
|
|
35
|
-
if (isArrayContext) {
|
|
36
|
-
arrayValues.push(trimmed.substring(1).trim())
|
|
37
|
-
}
|
|
38
|
-
continue
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// If we were in array context and hit a non-array line, save the array
|
|
42
|
-
if (isArrayContext) {
|
|
43
|
-
frontmatter[currentKey] = arrayValues.slice()
|
|
44
|
-
arrayValues.length = 0
|
|
45
|
-
isArrayContext = false
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Handle key-value pairs
|
|
49
|
-
const colonIndex = trimmed.indexOf(':')
|
|
50
|
-
if (colonIndex !== -1) {
|
|
51
|
-
const key = trimmed.substring(0, colonIndex).trim()
|
|
52
|
-
const value = trimmed.substring(colonIndex + 1).trim()
|
|
53
|
-
currentKey = key
|
|
54
|
-
|
|
55
|
-
// Empty value means an array follows on subsequent lines
|
|
56
|
-
if (value === '') {
|
|
57
|
-
isArrayContext = true
|
|
58
|
-
continue
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (value === 'true') frontmatter[currentKey] = true
|
|
62
|
-
else if (value === 'false') frontmatter[currentKey] = false
|
|
63
|
-
else frontmatter[currentKey] = stripQuotes(value)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Flush trailing array
|
|
68
|
-
if (isArrayContext && arrayValues.length > 0) {
|
|
69
|
-
frontmatter[currentKey] = arrayValues
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const content = rawContent.replace(/^---\s*\n[\s\S]*?\n---\s*\n/, '')
|
|
73
|
-
|
|
74
|
-
return { frontmatter, content }
|
|
75
|
-
}
|
package/types/index.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export type { ParsedFrontmatter } from './frontmatter'
|
|
2
|
-
export { parseFrontmatter } from './frontmatter'
|
|
3
|
-
|
|
4
|
-
export interface NavigationItem {
|
|
5
|
-
slug: string
|
|
6
|
-
hasAdvanced?: boolean
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface NavigationItemWithTitle extends NavigationItem {
|
|
10
|
-
title: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface NavigationSection {
|
|
14
|
-
title: string
|
|
15
|
-
items: NavigationItem[]
|
|
16
|
-
defaultOpen?: boolean
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface NavigationSectionWithTitles {
|
|
20
|
-
title: string
|
|
21
|
-
items: NavigationItemWithTitle[]
|
|
22
|
-
defaultOpen?: boolean
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type NavigationEntry = NavigationSection | NavigationItem
|
|
26
|
-
|
|
27
|
-
export type NavigationEntryWithTitles =
|
|
28
|
-
| NavigationSectionWithTitles
|
|
29
|
-
| NavigationItemWithTitle
|
|
30
|
-
|
|
31
|
-
export interface LoadedContent {
|
|
32
|
-
content: string
|
|
33
|
-
frontmatter: {
|
|
34
|
-
title?: string
|
|
35
|
-
hasAdvanced?: boolean
|
|
36
|
-
tags?: string[]
|
|
37
|
-
date?: string
|
|
38
|
-
author?: string
|
|
39
|
-
[key: string]: unknown
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export type SupportedLanguage = string
|