This commit is contained in:
Andras Schmelczer 2026-09-23 08:14:33 +01:00
commit 498eb47fd8
4 changed files with 26 additions and 29 deletions

View file

@ -0,0 +1,5 @@
/** Replace the complete metadata value atomically. */
export interface MetadataPersistenceProvider<T> {
load: () => Promise<T | undefined>;
save: (data: T) => Promise<void>;
}

View file

@ -1,8 +0,0 @@
/** save() atomically replaces the entire value and resolves only after both the
* data and its directory entry are durable across power loss. Failed saves must
* leave either complete value readable; callers retain their recovery journal.
*/
export interface PersistenceProvider<T> {
load: () => Promise<T | undefined>;
save: (data: T) => Promise<void>;
}

View file

@ -0,0 +1,87 @@
import { describe, it } from "node:test";
import assert from "node:assert";
import { isFileTypeMergeable } from "./is-file-type-mergeable";
const mergeableExtensions = ["md", "txt"];
describe("isFileTypeMergeable", () => {
it("should return true for .md files", () => {
assert.strictEqual(isFileTypeMergeable(".md", mergeableExtensions), true);
assert.strictEqual(
isFileTypeMergeable("hi.md", mergeableExtensions),
true
);
assert.strictEqual(
isFileTypeMergeable("my/path/to/my/document.md", mergeableExtensions),
true
);
});
it("should return true for .txt files", () => {
assert.strictEqual(
isFileTypeMergeable(".txt", mergeableExtensions),
true
);
assert.strictEqual(
isFileTypeMergeable("hi.txt", mergeableExtensions),
true
);
assert.strictEqual(
isFileTypeMergeable(
"my/path/to/my/document.txt",
mergeableExtensions
),
true
);
});
it("should be case insensitive", () => {
assert.strictEqual(
isFileTypeMergeable("hi.MD", mergeableExtensions),
true
);
assert.strictEqual(
isFileTypeMergeable("my/path/to/my/DOCUMENT.MD", mergeableExtensions),
true
);
assert.strictEqual(
isFileTypeMergeable("hi.TXT", mergeableExtensions),
true
);
assert.strictEqual(
isFileTypeMergeable(
"my/path/to/my/DOCUMENT.TXT",
mergeableExtensions
),
true
);
});
it("should return false for non-mergeable file types", () => {
assert.strictEqual(
isFileTypeMergeable(".json", mergeableExtensions),
false
);
assert.strictEqual(
isFileTypeMergeable("HELLO.JSON", mergeableExtensions),
false
);
assert.strictEqual(
isFileTypeMergeable("my/config.yml", mergeableExtensions),
false
);
});
});
for (const path of [
"md",
"txt",
"nested/md",
"nested/txt",
"a.md/txt",
"a.txt/md",
"note."
]) {
it(`does not merge an extensionless file: ${path}`, () => {
assert.equal(isFileTypeMergeable(path, ["md", "txt"]), false);
});
}

View file

@ -0,0 +1,11 @@
export function isFileTypeMergeable(
pathOrFileName: string,
mergeableExtensions: string[]
): boolean {
const name = pathOrFileName.split("/").at(-1) ?? "";
const separator = name.lastIndexOf(".");
if (separator < 0) return false;
const fileExtension = name.slice(separator + 1);
return mergeableExtensions.includes(fileExtension.toLowerCase());
}