@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 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 20 articles (for the home page)
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 = 20
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) return { frontmatter: {}, content: e };
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-wave/blog",
3
- "version": "2.7.3",
3
+ "version": "2.7.5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -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"}
@@ -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,2 @@
1
+ export { parseFrontmatter } from './frontmatter.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
@@ -1,4 +1,4 @@
1
- import { parseFrontmatter } from 'types';
1
+ import { parseFrontmatter } from '../types/index.js';
2
2
  /**
3
3
  * Extract language from file path based on doc structure
4
4
  * Expected: docs/[language]/[slug].mdx
@@ -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