@natilon/cms-server 0.10.0 → 0.10.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@natilon/cms-server",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "Express-based CMS server with pluggable adapters for content, media, auth, and build.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -25,6 +25,18 @@ export function safeFileName(name) {
25
25
  return name;
26
26
  }
27
27
 
28
+ /**
29
+ * True when a filename is a content entry (and not a generated manifest such
30
+ * as `_index.json`). Manifest/index files are list projections, not entries,
31
+ * so every directory-scan that enumerates entries must exclude them.
32
+ *
33
+ * @param {string} file
34
+ * @returns {boolean}
35
+ */
36
+ export function isEntryFile(file) {
37
+ return typeof file === "string" && file.endsWith(".json") && !file.startsWith("_");
38
+ }
39
+
28
40
  /**
29
41
  * Sorts a pages array in-place and returns it.
30
42
  *
@@ -1,7 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import { execSync } from "child_process";
4
- import { sanitize, safeFileName, sortPages, buildDuplicateData, listScheduledDue, buildListEntry, relationFields } from "./_shared.mjs";
4
+ import { sanitize, safeFileName, sortPages, buildDuplicateData, listScheduledDue, buildListEntry, relationFields, isEntryFile } from "./_shared.mjs";
5
5
 
6
6
  const HISTORY_KEEP = 50; // max revisions kept per file
7
7
 
@@ -65,7 +65,7 @@ export function createFsJsonContent({
65
65
  return dirs.map((dir) => {
66
66
  const files = fs
67
67
  .readdirSync(path.join(PAGES_DIR, dir))
68
- .filter((f) => f.endsWith(".json"));
68
+ .filter(isEntryFile);
69
69
  return { name: dir, count: files.length };
70
70
  });
71
71
  },
@@ -84,7 +84,7 @@ export function createFsJsonContent({
84
84
  if (!fs.existsSync(targetDir)) continue;
85
85
  const table = {};
86
86
  for (const f of fs.readdirSync(targetDir)) {
87
- if (!f.endsWith(".json") || f === "_index.json") continue;
87
+ if (!isEntryFile(f)) continue;
88
88
  try {
89
89
  const d = JSON.parse(fs.readFileSync(path.join(targetDir, f), "utf-8"));
90
90
  if (d.slug) table[d.slug] = d.meta?.title || d.meta?.name || d.slug;
@@ -95,7 +95,7 @@ export function createFsJsonContent({
95
95
  lookups[target] = table;
96
96
  }
97
97
 
98
- const files = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
98
+ const files = fs.readdirSync(dir).filter(isEntryFile);
99
99
  const pages = files.map((file) => {
100
100
  const data = JSON.parse(fs.readFileSync(path.join(dir, file), "utf-8"));
101
101
  return buildListEntry(collections[collection], collection, file, data, lookups);