koguma 2.0.0 → 2.1.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/README.md CHANGED
@@ -149,7 +149,7 @@ content/
149
149
  │ ├── hello-world.md # file = one entry
150
150
  │ └── our-mission.md
151
151
  ├── siteSettings/
152
- │ └── index.yml # singletons use index.yml
152
+ │ └── index.md # singletons use index.md
153
153
  └── media/ # optional local images
154
154
  └── hero-banner.jpg
155
155
  ```
@@ -244,7 +244,7 @@ Your Project
244
244
  ├── post/
245
245
  │ └── hello-world.md
246
246
  └── siteSettings/
247
- └── index.yml
247
+ └── index.md
248
248
 
249
249
  Koguma (this package)
250
250
  ├── src/
package/cli/content.ts CHANGED
@@ -8,14 +8,16 @@
8
8
  * │ ├── hello-world.md # markdown body + frontmatter
9
9
  * │ └── our-mission.md
10
10
  * ├── siteSettings/
11
- * │ └── index.yml # singletons use index.yml
11
+ * │ └── index.md # singletons use index.md
12
12
  * └── media/ # optional local images (not managed here)
13
13
  * └── hero.jpg
14
14
  *
15
- * Markdown files use YAML frontmatter for structured fields.
15
+ * All content files use the .md extension with YAML frontmatter.
16
16
  * The file body (below the frontmatter) is mapped to the first `markdown`
17
- * field in the content type definition. If the content type has no markdown
18
- * field, YAML-only files (.yml) are used.
17
+ * field in the content type definition. Files without a markdown field
18
+ * are frontmatter-only .md files (no body below the --- delimiter).
19
+ *
20
+ * Legacy .yml files are still accepted on read for backwards compatibility.
19
21
  */
20
22
 
21
23
  import matter from 'gray-matter';
@@ -36,7 +38,7 @@ export interface ContentEntry {
36
38
  contentType: string;
37
39
  /** Slug derived from filename (without extension) */
38
40
  slug: string;
39
- /** Whether this is a singleton (index.yml) */
41
+ /** Whether this is a singleton (index.md) */
40
42
  singleton: boolean;
41
43
  /** All frontmatter fields */
42
44
  fields: Record<string, unknown>;
@@ -56,7 +58,8 @@ export interface ContentTypeInfo {
56
58
  // ── Parse a single content file ────────────────────────────────────
57
59
 
58
60
  /**
59
- * Parse a .md or .yml file into a ContentEntry.
61
+ * Parse a .md or .yml/.yaml file into a ContentEntry.
62
+ * (.yml/.yaml are accepted for backwards compatibility)
60
63
  */
61
64
  export function parseContentFile(
62
65
  filePath: string,
@@ -65,7 +68,7 @@ export function parseContentFile(
65
68
  const raw = readFileSync(filePath, 'utf-8');
66
69
  const ext = extname(filePath).toLowerCase();
67
70
  const name = basename(filePath, ext);
68
- const singleton = name === 'index' && ext === '.yml';
71
+ const singleton = name === 'index' && (ext === '.yml' || ext === '.md');
69
72
 
70
73
  if (ext === '.yml' || ext === '.yaml') {
71
74
  // YAML-only file (no markdown body)
@@ -97,8 +100,8 @@ export function parseContentFile(
97
100
 
98
101
  return {
99
102
  contentType,
100
- slug: name,
101
- singleton: false,
103
+ slug: singleton ? contentType : name,
104
+ singleton,
102
105
  fields: parsed.data,
103
106
  body,
104
107
  filePath
@@ -252,15 +255,15 @@ export function dbRowToContentFile(
252
255
  };
253
256
  }
254
257
 
255
- // YAML-only file (no markdown field or empty body)
258
+ // Frontmatter-only file (no markdown field or empty body)
256
259
  const fm = matter.stringify('', fields).trim();
257
- return { content: fm + '\n', extension: '.yml' };
260
+ return { content: fm + '\n', extension: '.md' };
258
261
  }
259
262
 
260
263
  // ── Write content/ directory from D1 entries ───────────────────────
261
264
 
262
265
  /**
263
- * Write D1 entries to the content/ directory as .md/.yml files.
266
+ * Write D1 entries to the content/ directory as .md files.
264
267
  * Each content type gets its own subdirectory.
265
268
  *
266
269
  * @param contentDir - Absolute path to the content/ directory
package/cli/scaffold.ts CHANGED
@@ -337,7 +337,7 @@ export function generateExampleFile(
337
337
  }
338
338
 
339
339
  const fm = matter.stringify('', frontmatter).trim();
340
- return { content: fm + '\n', extension: '.yml' };
340
+ return { content: fm + '\n', extension: '.md' };
341
341
  }
342
342
 
343
343
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koguma",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "🐻 A little CMS with big heart — schema-driven, runs on Cloudflare's free tier",
5
5
  "type": "module",
6
6
  "license": "MIT",