mirror of
https://github.com/def-peter/obsidian-aera-theme.git
synced 2026-07-22 05:00:27 +00:00
fix: preserve vault notes and user fonts
This commit is contained in:
parent
fcd3d9f1e0
commit
4cec652800
8 changed files with 82 additions and 7 deletions
|
|
@ -11,9 +11,11 @@ dark, desktop, and mobile support.
|
|||
|
||||
Run `npm install`, `npm run build`, and `npm run check`.
|
||||
|
||||
For live preview, set `AERA_TEST_VAULT`, then run `npm run link:vault` and
|
||||
`npm run dev`. Changes to `manifest.json` require an Obsidian restart, while
|
||||
compiled CSS changes automatically reload in the linked vault.
|
||||
For live preview, set `AERA_TEST_VAULT` to a dedicated test vault, then run
|
||||
`npm run link:vault` and `npm run dev`. The linker refuses to replace unknown
|
||||
notes named `Theme Playground.md` or `Embedded Note.md`. Changes to
|
||||
`manifest.json` require an Obsidian restart, while
|
||||
compiled CSS automatically reloads in the linked vault.
|
||||
|
||||
## Release assets
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,5 @@
|
|||
这是一篇用于验证 `[[Embedded Note]]` 已解析内部链接与嵌入预览的中文笔记。
|
||||
|
||||
返回 [[Theme Playground]]。
|
||||
|
||||
<!-- Aera fixture managed by obsidian-aera-theme. -->
|
||||
|
|
|
|||
|
|
@ -66,3 +66,5 @@ published: 2026-07-16
|
|||
演练场以脚注引用结束。[^aera]
|
||||
|
||||
[^aera]: Aera 是用于检查 Obsidian 主题的演练 fixture。
|
||||
|
||||
<!-- Aera fixture managed by obsidian-aera-theme. -->
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import { fileURLToPath } from "node:url";
|
|||
const modulePath = fileURLToPath(import.meta.url);
|
||||
const defaultRepoPath = dirname(dirname(modulePath));
|
||||
const fixtureNames = ["Theme Playground.md", "Embedded Note.md"];
|
||||
const fixtureOwnershipMarker =
|
||||
"<!-- Aera fixture managed by obsidian-aera-theme. -->";
|
||||
|
||||
async function existingPathType(path) {
|
||||
try {
|
||||
|
|
@ -55,6 +57,17 @@ async function assertSafeFixtureTarget(path) {
|
|||
throw new Error(`Refusing to replace fixture ${type} at ${path}`);
|
||||
}
|
||||
|
||||
async function assertManagedFixtureTarget(path) {
|
||||
const existing = await existingPathType(path);
|
||||
if (!existing) return;
|
||||
|
||||
await assertSafeFixtureTarget(path);
|
||||
const contents = await readFile(path, "utf8");
|
||||
if (!contents.trimEnd().endsWith(fixtureOwnershipMarker)) {
|
||||
throw new Error(`Refusing to replace unknown fixture at ${path}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function copyFixtureSafely(
|
||||
sourcePath,
|
||||
destinationPath,
|
||||
|
|
@ -140,7 +153,7 @@ export async function linkVault(vaultPath, repoPath = defaultRepoPath) {
|
|||
source: join(repo, "fixtures", name),
|
||||
}));
|
||||
for (const { destination } of fixtures) {
|
||||
await assertSafeFixtureTarget(destination);
|
||||
await assertManagedFixtureTarget(destination);
|
||||
}
|
||||
for (const { destination, source } of fixtures) {
|
||||
await copyFixtureSafely(source, destination);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
body {
|
||||
--inline-title-color: var(--text-normal);
|
||||
--inline-title-font: var(--font-text-theme);
|
||||
--inline-title-font: var(--font-text);
|
||||
--inline-title-line-height: 1.25;
|
||||
--inline-title-size: 2em;
|
||||
--inline-title-weight: 650;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ function assertDeclarations(expected) {
|
|||
test("defines the inline title hierarchy", () => {
|
||||
assertDeclarations({
|
||||
"--inline-title-color": "var(--text-normal)",
|
||||
"--inline-title-font": "var(--font-text-theme)",
|
||||
"--inline-title-font": "var(--font-text)",
|
||||
"--inline-title-line-height": "1.25",
|
||||
"--inline-title-size": "2em",
|
||||
"--inline-title-weight": "650",
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ import {
|
|||
const repoRoot = dirname(fileURLToPath(new URL("../package.json", import.meta.url)));
|
||||
const cliPath = join(repoRoot, "scripts/link-vault.mjs");
|
||||
const fixtureNames = ["Theme Playground.md", "Embedded Note.md"];
|
||||
const fixtureOwnershipMarker =
|
||||
"<!-- Aera fixture managed by obsidian-aera-theme. -->";
|
||||
|
||||
async function createVault(t) {
|
||||
const vault = await mkdtemp(join(tmpdir(), "aera-vault-"));
|
||||
|
|
@ -71,6 +73,58 @@ test("linkVault links Aera and copies the playground fixtures", async (t) => {
|
|||
}
|
||||
});
|
||||
|
||||
test("linkVault updates fixtures carrying the Aera ownership marker", async (t) => {
|
||||
const vault = await createVault(t);
|
||||
|
||||
for (const name of fixtureNames) {
|
||||
await writeFile(
|
||||
join(vault, name),
|
||||
`stale fixture\n\n${fixtureOwnershipMarker}\n`,
|
||||
);
|
||||
}
|
||||
|
||||
await linkVault(vault, repoRoot);
|
||||
|
||||
for (const name of fixtureNames) {
|
||||
assert.equal(
|
||||
await readFile(join(vault, name), "utf8"),
|
||||
await readFile(join(repoRoot, "fixtures", name), "utf8"),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
for (const unknownFixture of fixtureNames) {
|
||||
test(`linkVault rejects an unknown ${unknownFixture} before updating any fixture`, async (t) => {
|
||||
const vault = await createVault(t);
|
||||
const originalContents = new Map();
|
||||
|
||||
for (const name of fixtureNames) {
|
||||
const contents =
|
||||
name === unknownFixture
|
||||
? `personal ${name} content\n`
|
||||
: `stale owned ${name}\n\n${fixtureOwnershipMarker}\n`;
|
||||
originalContents.set(name, contents);
|
||||
await writeFile(join(vault, name), contents);
|
||||
}
|
||||
|
||||
await assert.rejects(
|
||||
linkVault(vault, repoRoot),
|
||||
new RegExp(`Refusing to replace unknown fixture.*${unknownFixture}`, "i"),
|
||||
);
|
||||
|
||||
for (const name of fixtureNames) {
|
||||
assert.equal(
|
||||
await readFile(join(vault, name), "utf8"),
|
||||
originalContents.get(name),
|
||||
);
|
||||
}
|
||||
assert.equal(
|
||||
(await readdir(vault)).some((name) => /aera.*tmp|\.tmp/i.test(name)),
|
||||
false,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test("the playground fixture covers the supported Markdown elements", async () => {
|
||||
const playground = await readFile(
|
||||
join(repoRoot, "fixtures", "Theme Playground.md"),
|
||||
|
|
@ -118,6 +172,7 @@ test("the playground fixture covers the supported Markdown elements", async () =
|
|||
assert.match(playground, /^!\[\[Embedded Note\]\]$/m);
|
||||
assert.match(playground, /^演练场以脚注引用结束。\[\^aera\]$/m);
|
||||
assert.match(playground, /^\[\^aera\]: Aera 是用于检查 Obsidian 主题的演练 fixture。$/m);
|
||||
assert.equal(playground.endsWith(`${fixtureOwnershipMarker}\n`), true);
|
||||
|
||||
const embedded = await readFile(
|
||||
join(repoRoot, "fixtures", "Embedded Note.md"),
|
||||
|
|
@ -126,6 +181,7 @@ test("the playground fixture covers the supported Markdown elements", async () =
|
|||
assert.match(embedded, /^# 嵌入内容$/m);
|
||||
assert.match(embedded, /^这是一篇用于验证 `\[\[Embedded Note\]\]` 已解析内部链接与嵌入预览的中文笔记。$/m);
|
||||
assert.match(embedded, /^返回 \[\[Theme Playground\]\]。$/m);
|
||||
assert.equal(embedded.endsWith(`${fixtureOwnershipMarker}\n`), true);
|
||||
});
|
||||
|
||||
for (const fixtureName of fixtureNames) {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ body {
|
|||
|
||||
body {
|
||||
--inline-title-color: var(--text-normal);
|
||||
--inline-title-font: var(--font-text-theme);
|
||||
--inline-title-font: var(--font-text);
|
||||
--inline-title-line-height: 1.25;
|
||||
--inline-title-size: 2em;
|
||||
--inline-title-weight: 650;
|
||||
|
|
|
|||
Loading…
Reference in a new issue