






























@@ -20,6 +20,7 @@ import {
2020WIKI_RELATED_START_MARKER,
2121} from "./markdown.js";
2222import { resolveMemoryWikiTimestamp } from "./time.js";
23+import { isRegularFileStat, writeGuardedVaultPage } from "./vault-page-write.js";
2324import { initializeMemoryWikiVault } from "./vault.js";
24252526const OKF_RESERVED_FILENAMES = new Set(["index.md", "log.md"]);
@@ -32,11 +33,6 @@ const OKF_RELATED_SECTION_PATTERN = new RegExp(
3233const OKF_VOLATILE_TIMESTAMP_LINE_PATTERN = /^(?:importedAt|updatedAt): .*\n/gm;
3334const OKF_HASH_CHARS = 8;
343535-type FileStatLike = {
36-isFile?: unknown;
37-nlink?: unknown;
38-};
39-4036type OkfConceptDocument = {
4137conceptId: string;
4238relativePath: string;
@@ -88,18 +84,6 @@ function trimMarkdownExtension(value: string): string {
8884return value.replace(/\.md$/i, "");
8985}
908691-function isRegularFileStat(value: unknown): value is FileStatLike & { nlink: number } {
92-if (!value || typeof value !== "object") {
93-return false;
94-}
95-const stat = value as FileStatLike;
96-const isFile =
97-typeof stat.isFile === "function"
98- ? (stat.isFile as () => boolean).call(stat)
99- : stat.isFile === true;
100-return isFile && typeof stat.nlink === "number";
101-}
102-10387type OkfBundleMetadata = {
10488key: string;
10589version?: string;
@@ -344,11 +328,12 @@ function safeDecodeOkfLinkPath(value: string | undefined): string {
344328function getMarkdownDestinationSuffix(destination: string): string {
345329const queryIndex = destination.indexOf("?");
346330const fragmentIndex = destination.indexOf("#");
347-const suffixIndex = queryIndex === -1
348- ? fragmentIndex
349- : fragmentIndex === -1
350- ? queryIndex
351- : Math.min(queryIndex, fragmentIndex);
331+const suffixIndex =
332+queryIndex === -1
333+ ? fragmentIndex
334+ : fragmentIndex === -1
335+ ? queryIndex
336+ : Math.min(queryIndex, fragmentIndex);
352337return suffixIndex === -1 ? "" : destination.slice(suffixIndex);
353338}
354339@@ -481,25 +466,13 @@ async function writeOkfConceptPage(params: {
481466) {
482467return { changed: false, created: !pageStat };
483468}
484-try {
485-if (isRegularFileStat(pageStat) && pageStat.nlink > 1) {
486-await vault.remove(params.pagePath);
487-}
488-await vault.write(params.pagePath, params.content);
489-} catch (error) {
490-if (error instanceof FsSafeError) {
491-if (error.code !== "symlink" && error.code !== "path-alias") {
492-throw new Error(
493-`Refusing to write OKF concept page (${error.code}): ${params.pagePath}: ${error.message}`,
494-{ cause: error },
495-);
496-}
497-throw new Error(`Refusing to write OKF concept page through symlink: ${params.pagePath}`, {
498-cause: error,
499-});
500-}
501-throw error;
502-}
469+await writeGuardedVaultPage({
470+ vault,
471+pagePath: params.pagePath,
472+content: params.content,
473+ pageStat,
474+pageLabel: "OKF concept page",
475+});
503476return { changed: true, created: !pageStat };
504477}
505478此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。