seemore 1.11.1 → 1.12.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
@@ -220,7 +220,8 @@ export default {
220
220
  search: 'static', // or { provider: 'orama-cloud', endpoint, apiKey } / { provider: 'algolia', appId, apiKey, indexName }
221
221
  pageActions: ['copy-markdown', 'export-html'],
222
222
  exclude: ['drafts/**'],
223
- auth: true, // password from SEEMORE_PASSWORD at build time
223
+ include: ['.notes'], // dot folders, build/, dist/ and similar are skipped unless listed here
224
+ auth: true,
224
225
  };
225
226
  ```
226
227
 
package/dist/cli/index.js CHANGED
@@ -78,7 +78,7 @@ import pc5 from "picocolors";
78
78
  import { mkdirSync as mkdirSync3, mkdtempSync, readFileSync as readFileSync7, rmSync, writeFileSync as writeFileSync7 } from "fs";
79
79
  import { createRequire as createRequire4 } from "module";
80
80
  import { tmpdir as tmpdir3 } from "os";
81
- import { isAbsolute as isAbsolute2, join as join12, relative as relative2, resolve as resolve5 } from "path";
81
+ import { isAbsolute as isAbsolute2, join as join12, relative as relative3, resolve as resolve5 } from "path";
82
82
  import pc2 from "picocolors";
83
83
  import { build as viteBuild } from "vite";
84
84
 
@@ -750,6 +750,8 @@ var configSchema = z.object({
750
750
  search: searchSchema.default("static"),
751
751
  pageActions: pageActionsSchema,
752
752
  exclude: z.array(z.string()).default([]),
753
+ /** Folders or globs to scan even though a default exclude (dot folders, `build/`, …) skips them. */
754
+ include: z.array(z.string()).default([]),
753
755
  auth: authSchema
754
756
  });
755
757
 
@@ -779,6 +781,7 @@ function resolveConfig(input, options) {
779
781
  search,
780
782
  pageActions: parsed.pageActions,
781
783
  exclude: parsed.exclude,
784
+ include: parsed.include,
782
785
  auth,
783
786
  root: options.root,
784
787
  configFile: options.configFile
@@ -958,9 +961,9 @@ function splitHash(value) {
958
961
  if (index === -1) return [value, void 0];
959
962
  return [value.slice(0, index), value.slice(index + 1)];
960
963
  }
961
- function joinPosix(fromDir, relative4) {
964
+ function joinPosix(fromDir, relative5) {
962
965
  const segments = [...fromDir];
963
- for (const part of toPosix(relative4).split("/")) {
966
+ for (const part of toPosix(relative5).split("/")) {
964
967
  if (part === "" || part === ".") continue;
965
968
  if (part === "..") segments.pop();
966
969
  else segments.push(part);
@@ -1046,14 +1049,9 @@ var metaSchema = z4.object({
1046
1049
  }).loose();
1047
1050
  function scan(options) {
1048
1051
  const contentRoot = resolve3(options.contentRoot);
1049
- const ignore = [...DEFAULT_EXCLUDES, ...options.exclude ?? []];
1050
- const contentFiles = globSync(["**/*.md", "**/*.mdx"], {
1051
- cwd: contentRoot,
1052
- ignore,
1053
- dot: false,
1054
- absolute: false
1055
- }).map(toPosix);
1056
- const metaFiles = globSync(["**/meta.json"], { cwd: contentRoot, ignore, dot: false, absolute: false }).map(toPosix);
1052
+ const find = (patterns, keep) => findFiles(contentRoot, patterns, keep, options.exclude ?? [], options.include ?? []);
1053
+ const contentFiles = find(["**/*.md", "**/*.mdx"], /\.mdx?$/);
1054
+ const metaFiles = find(["**/meta.json"], /(?:^|\/)meta\.json$/);
1057
1055
  const { routes, errors, warnings } = resolveRoutes(contentFiles);
1058
1056
  const pages = [];
1059
1057
  for (const route of routes) {
@@ -1100,6 +1098,17 @@ ${parsed.error.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.messa
1100
1098
  files.push(...synthesiseOrderMeta(pages, metaDirs));
1101
1099
  return { files, pages, errors, warnings };
1102
1100
  }
1101
+ function findFiles(contentRoot, patterns, keep, exclude, include) {
1102
+ const found = new Set(
1103
+ globSync(patterns, { cwd: contentRoot, ignore: [...DEFAULT_EXCLUDES, ...exclude], dot: false }).map(toPosix)
1104
+ );
1105
+ if (include.length > 0) {
1106
+ for (const file of globSync(include, { cwd: contentRoot, ignore: exclude, dot: true }).map(toPosix)) {
1107
+ if (keep.test(file)) found.add(file);
1108
+ }
1109
+ }
1110
+ return [...found];
1111
+ }
1103
1112
  function synthesiseOrderMeta(pages, metaDirs) {
1104
1113
  const byDir = /* @__PURE__ */ new Map();
1105
1114
  for (const page of pages) {
@@ -1202,6 +1211,7 @@ function createContext(options) {
1202
1211
  const source = createSource({
1203
1212
  contentRoot,
1204
1213
  exclude: config.exclude,
1214
+ include: config.include,
1205
1215
  siteTitle: config.title,
1206
1216
  includeDrafts: options.includeDrafts
1207
1217
  });
@@ -1841,8 +1851,27 @@ function readIfExists(path) {
1841
1851
  }
1842
1852
 
1843
1853
  // src/node/vite/watcher.ts
1854
+ import { relative as relative2 } from "path";
1844
1855
  import chokidar from "chokidar";
1845
1856
  var CONTENT_FILE = /\.(?:mdx?|json)$/i;
1857
+ var EXCLUDED_DIR = /(?:^|\/)(?:node_modules|dist|build|out|vendor|target|venv|deps|Pods|bower_components|\.[^/]+)(?:$|\/)/;
1858
+ var ALWAYS_EXCLUDED_DIR = /(?:^|\/)(?:node_modules|\.git)(?:$|\/)/;
1859
+ var GLOB_CHAR = /[*?[\]{}()!]/;
1860
+ function isWatchIgnored(relativePath, isFile, include) {
1861
+ const rel = relativePath.replace(/\\/g, "/");
1862
+ if (rel !== "" && EXCLUDED_DIR.test(rel) && !include.some((pattern) => reaches(pattern, rel))) return true;
1863
+ return isFile && !CONTENT_FILE.test(rel);
1864
+ }
1865
+ function reaches(pattern, rel) {
1866
+ const base = [];
1867
+ for (const segment of pattern.replace(/^\.\//, "").split("/")) {
1868
+ if (GLOB_CHAR.test(segment)) break;
1869
+ base.push(segment);
1870
+ }
1871
+ const dir = base.join("/");
1872
+ if (dir === "") return !ALWAYS_EXCLUDED_DIR.test(rel);
1873
+ return rel === dir || rel.startsWith(`${dir}/`) || dir.startsWith(`${rel}/`);
1874
+ }
1846
1875
  function seemoreWatcherPlugin(ctx) {
1847
1876
  let watcher;
1848
1877
  return {
@@ -1853,10 +1882,7 @@ function seemoreWatcherPlugin(ctx) {
1853
1882
  ignoreInitial: true,
1854
1883
  ignored: (path, stats) => {
1855
1884
  if (path === ctx.config.configFile) return false;
1856
- const posix = path.replace(/\\/g, "/");
1857
- if (/(?:^|\/)(?:node_modules|\.git|dist|build|out|vendor|target|\.seemore)(?:$|\/)/.test(posix)) return true;
1858
- if (/(?:^|\/)\.[^/]+/.test(posix)) return true;
1859
- return stats?.isFile() === true && !CONTENT_FILE.test(posix);
1885
+ return isWatchIgnored(relative2(ctx.contentRoot, path), stats?.isFile() === true, ctx.config.include);
1860
1886
  }
1861
1887
  });
1862
1888
  const onEvent = (event, path) => {
@@ -2155,7 +2181,7 @@ async function runBuild(options) {
2155
2181
  throw new Error(`No Markdown files found under ${contentRoot}. Point seemore at a folder that has some, or check \`exclude\`.`);
2156
2182
  }
2157
2183
  for (const warning of scan2.warnings) ctx.warnings.add(warning);
2158
- console.log(pc2.dim(`seemore ${scan2.pages.length} pages from ${relative2(options.cwd, contentRoot) || "."}`));
2184
+ console.log(pc2.dim(`seemore ${scan2.pages.length} pages from ${relative3(options.cwd, contentRoot) || "."}`));
2159
2185
  await viteBuild(createViteConfig({ ctx, mode: "build", outDir, auth: password !== void 0 }));
2160
2186
  const template = readFileSync7(join12(outDir, "index.html"), "utf8");
2161
2187
  const routes = password === void 0 ? await prerenderPages(ctx, outDir, template) : countRoutes(ctx);
@@ -2174,7 +2200,7 @@ async function runBuild(options) {
2174
2200
  console.log(pc2.dim(`seemore ${encrypted} files encrypted; visitors unlock them with the password`));
2175
2201
  }
2176
2202
  ctx.warnings.flush();
2177
- console.log(pc2.green(`seemore ${routes} pages written to ${relative2(options.cwd, outDir) || outDir}`));
2203
+ console.log(pc2.green(`seemore ${routes} pages written to ${relative3(options.cwd, outDir) || outDir}`));
2178
2204
  return { outDir, routes };
2179
2205
  }
2180
2206
  async function prerenderPages(ctx, outDir, template) {
@@ -2203,7 +2229,7 @@ function countRoutes(ctx) {
2203
2229
  }
2204
2230
  function assertSafeOutDir(outDir, cwd, contentRoot) {
2205
2231
  const contains = (parent, child) => {
2206
- const rel = relative2(parent, child);
2232
+ const rel = relative3(parent, child);
2207
2233
  return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
2208
2234
  };
2209
2235
  for (const [name, dir] of [
@@ -2304,7 +2330,7 @@ async function runDev(options) {
2304
2330
 
2305
2331
  // src/cli/export.ts
2306
2332
  import { existsSync as existsSync4, mkdtempSync as mkdtempSync2, readFileSync as readFileSync8, readdirSync as readdirSync2, rmSync as rmSync2, statSync, writeFileSync as writeFileSync8, mkdirSync as mkdirSync4 } from "fs";
2307
- import { basename as basename2, dirname as dirname9, extname, join as join13, relative as relative3, resolve as resolve6 } from "path";
2333
+ import { basename as basename2, dirname as dirname9, extname, join as join13, relative as relative4, resolve as resolve6 } from "path";
2308
2334
  import { tmpdir as tmpdir4 } from "os";
2309
2335
  import pc4 from "picocolors";
2310
2336
  import { build as viteBuild2 } from "vite";
@@ -2363,7 +2389,7 @@ ${errors.join("\n\n")}`);
2363
2389
  }
2364
2390
  const page = ctx.pages().find((candidate) => candidate.absPath === canonicalise(target));
2365
2391
  if (page === void 0) {
2366
- throw new Error(`${options.file} is not part of this site \u2014 excluded in the config, or outside ${relative3(options.cwd, contentRoot) || "."}.`);
2392
+ throw new Error(`${options.file} is not part of this site \u2014 excluded in the config, or outside ${relative4(options.cwd, contentRoot) || "."}.`);
2367
2393
  }
2368
2394
  const outDir = mkdtempSync2(join13(tmpdir4(), "seemore-export-"));
2369
2395
  const ssrOutDir = mkdtempSync2(join13(tmpdir4(), "seemore-export-ssr-"));
@@ -2378,12 +2404,12 @@ ${errors.join("\n\n")}`);
2378
2404
  const filename = `${basename2(target).replace(/\.(?:md|mdx)$/i, "")}.html`;
2379
2405
  const targetPath = options.out === void 0 ? join13(dirname9(target), filename) : join13(resolve6(options.cwd, options.out), filename);
2380
2406
  if (existsSync4(targetPath)) {
2381
- console.log(pc4.yellow(`seemore replacing existing ${relative3(options.cwd, targetPath) || targetPath}`));
2407
+ console.log(pc4.yellow(`seemore replacing existing ${relative4(options.cwd, targetPath) || targetPath}`));
2382
2408
  }
2383
2409
  mkdirSync4(dirname9(targetPath), { recursive: true });
2384
2410
  writeFileSync8(targetPath, html, "utf8");
2385
2411
  ctx.warnings.flush();
2386
- console.log(pc4.green(`seemore wrote ${relative3(options.cwd, targetPath) || targetPath} (${formatBytes2(html.length)})`));
2412
+ console.log(pc4.green(`seemore wrote ${relative4(options.cwd, targetPath) || targetPath} (${formatBytes2(html.length)})`));
2387
2413
  } finally {
2388
2414
  rmSync2(outDir, { recursive: true, force: true });
2389
2415
  rmSync2(ssrOutDir, { recursive: true, force: true });