@wizzlethorpe/vaults 0.6.1 → 0.7.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/README.md +135 -17
- package/dist/build.js +501 -190
- package/dist/build.js.map +1 -1
- package/dist/commands/build.js +4 -4
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/init.js +13 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/password.js +3 -1
- package/dist/commands/password.js.map +1 -1
- package/dist/commands/patreon.js +30 -20
- package/dist/commands/patreon.js.map +1 -1
- package/dist/commands/preview.js +10 -8
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/push.js +11 -9
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/role.js +5 -0
- package/dist/commands/role.js.map +1 -1
- package/dist/config.js +30 -15
- package/dist/config.js.map +1 -1
- package/dist/escape.js +29 -0
- package/dist/escape.js.map +1 -0
- package/dist/favicon.js +3 -36
- package/dist/favicon.js.map +1 -1
- package/dist/foundry-importer.js +61 -0
- package/dist/foundry-importer.js.map +1 -0
- package/dist/images.js +0 -30
- package/dist/images.js.map +1 -1
- package/dist/index.js +37 -4
- package/dist/index.js.map +1 -1
- package/dist/migrate/0.6-legacy-auth-settings.js +96 -0
- package/dist/migrate/0.6-legacy-auth-settings.js.map +1 -0
- package/dist/migrate/0.7-vaults-dir.js +74 -0
- package/dist/migrate/0.7-vaults-dir.js.map +1 -0
- package/dist/migrate/registry.js +6 -0
- package/dist/migrate/registry.js.map +1 -0
- package/dist/migrate/run.js +38 -0
- package/dist/migrate/run.js.map +1 -0
- package/dist/migrate/types.js +8 -0
- package/dist/migrate/types.js.map +1 -0
- package/dist/paths.js +66 -0
- package/dist/paths.js.map +1 -0
- package/dist/render/auth-template.js +23 -141
- package/dist/render/auth-template.js.map +1 -1
- package/dist/render/bases.js +56 -44
- package/dist/render/bases.js.map +1 -1
- package/dist/render/callouts.js +29 -10
- package/dist/render/callouts.js.map +1 -1
- package/dist/render/embed.js +124 -26
- package/dist/render/embed.js.map +1 -1
- package/dist/render/extensions.js +68 -0
- package/dist/render/extensions.js.map +1 -0
- package/dist/render/external-links.js +32 -0
- package/dist/render/external-links.js.map +1 -0
- package/dist/render/footer.js +37 -0
- package/dist/render/footer.js.map +1 -0
- package/dist/render/frontmatter.js +17 -0
- package/dist/render/frontmatter.js.map +1 -0
- package/dist/render/handlers/assets.js +123 -0
- package/dist/render/handlers/assets.js.map +1 -0
- package/dist/render/handlers/builtin/battlemap.js +199 -0
- package/dist/render/handlers/builtin/battlemap.js.map +1 -0
- package/dist/render/handlers/builtin/dice.js +78 -0
- package/dist/render/handlers/builtin/dice.js.map +1 -0
- package/dist/render/handlers/builtin/fm-code.js +50 -0
- package/dist/render/handlers/builtin/fm-code.js.map +1 -0
- package/dist/render/handlers/builtin/fm.js +83 -0
- package/dist/render/handlers/builtin/fm.js.map +1 -0
- package/dist/render/handlers/builtin/index.js +13 -0
- package/dist/render/handlers/builtin/index.js.map +1 -0
- package/dist/render/handlers/builtin/inline-format.js +26 -0
- package/dist/render/handlers/builtin/inline-format.js.map +1 -0
- package/dist/render/handlers/builtin/statblock.js +491 -0
- package/dist/render/handlers/builtin/statblock.js.map +1 -0
- package/dist/render/handlers/dispatch.js +182 -0
- package/dist/render/handlers/dispatch.js.map +1 -0
- package/dist/render/handlers/loader.js +90 -0
- package/dist/render/handlers/loader.js.map +1 -0
- package/dist/render/handlers/types.js +60 -0
- package/dist/render/handlers/types.js.map +1 -0
- package/dist/render/image-srcs.js +42 -0
- package/dist/render/image-srcs.js.map +1 -0
- package/dist/render/layout.js +62 -9
- package/dist/render/layout.js.map +1 -1
- package/dist/render/pipeline.js +38 -9
- package/dist/render/pipeline.js.map +1 -1
- package/dist/render/preview.js +53 -18
- package/dist/render/preview.js.map +1 -1
- package/dist/render/slug.js +5 -0
- package/dist/render/slug.js.map +1 -1
- package/dist/render/styles.js +124 -15
- package/dist/render/styles.js.map +1 -1
- package/dist/render/wikilink.js +15 -4
- package/dist/render/wikilink.js.map +1 -1
- package/dist/scan.js +1 -1
- package/dist/scan.js.map +1 -1
- package/dist/settings.js +25 -4
- package/dist/settings.js.map +1 -1
- package/dist/version.js +36 -0
- package/dist/version.js.map +1 -0
- package/package.json +12 -12
- package/dist/api.js +0 -42
- package/dist/api.js.map +0 -1
- package/dist/render/mcp-template.js +0 -239
- package/dist/render/mcp-template.js.map +0 -1
package/dist/commands/push.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
import { basename
|
|
1
|
+
import { basename } from "node:path";
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
3
|
import { createInterface } from "node:readline/promises";
|
|
4
4
|
import { stdin, stdout } from "node:process";
|
|
5
5
|
import { loadConfig, saveConfig, saveSessionSecret } from "../config.js";
|
|
6
6
|
import { buildSite } from "../build.js";
|
|
7
7
|
import { generateSessionSecret } from "../auth.js";
|
|
8
|
+
import { runMigrations } from "../migrate/run.js";
|
|
9
|
+
import { defaultOutputDir, requireInitialisedVault } from "../paths.js";
|
|
10
|
+
import { escapeRegex } from "../escape.js";
|
|
8
11
|
export async function push(vaultPath, opts) {
|
|
12
|
+
await requireInitialisedVault(vaultPath);
|
|
13
|
+
await runMigrations(vaultPath);
|
|
9
14
|
const cfg = await loadConfig(vaultPath, {
|
|
10
15
|
...(opts.projectName ? { projectName: opts.projectName } : {}),
|
|
11
16
|
...(opts.imageQuality != null ? { imageQuality: opts.imageQuality } : {}),
|
|
12
17
|
});
|
|
13
18
|
const vaultName = opts.vaultName ?? "Vault";
|
|
14
|
-
const outputDir =
|
|
19
|
+
const outputDir = defaultOutputDir(vaultPath);
|
|
15
20
|
console.log(`Building site from ${vaultPath}...`);
|
|
16
21
|
const result = await buildSite({
|
|
17
22
|
vaultPath,
|
|
@@ -56,8 +61,8 @@ export async function push(vaultPath, opts) {
|
|
|
56
61
|
// this on every push (not just first) so a `vaults patreon configure`
|
|
57
62
|
// that updates the secret without rotating the session also takes
|
|
58
63
|
// effect — Wrangler's secret put is idempotent for the same value.
|
|
59
|
-
if (cfg.patreon?.clientSecret) {
|
|
60
|
-
await wranglerSecret(cfg.projectName, "PATREON_CLIENT_SECRET", cfg.patreon.clientSecret);
|
|
64
|
+
if (cfg.oauth?.patreon?.clientSecret) {
|
|
65
|
+
await wranglerSecret(cfg.projectName, "PATREON_CLIENT_SECRET", cfg.oauth.patreon.clientSecret);
|
|
61
66
|
}
|
|
62
67
|
await wranglerDeploy(outputDir, cfg.projectName);
|
|
63
68
|
}
|
|
@@ -117,7 +122,7 @@ async function pagesProjectExists(name) {
|
|
|
117
122
|
try {
|
|
118
123
|
const out = await runWranglerCaptured(["pages", "project", "list"]);
|
|
119
124
|
// wrangler prints a table; check for the project name as a whole word.
|
|
120
|
-
const re = new RegExp(`(^|\\s|\\|)${
|
|
125
|
+
const re = new RegExp(`(^|\\s|\\|)${escapeRegex(name)}(\\s|\\||$)`, "m");
|
|
121
126
|
return re.test(out);
|
|
122
127
|
}
|
|
123
128
|
catch {
|
|
@@ -125,9 +130,6 @@ async function pagesProjectExists(name) {
|
|
|
125
130
|
return false;
|
|
126
131
|
}
|
|
127
132
|
}
|
|
128
|
-
function escapeRe(s) {
|
|
129
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
130
|
-
}
|
|
131
133
|
async function promptIfTty(question, fallback, nonTtyError) {
|
|
132
134
|
if (!stdin.isTTY) {
|
|
133
135
|
if (fallback) {
|
|
@@ -150,7 +152,7 @@ async function wranglerDeploy(outputDir, projectName) {
|
|
|
150
152
|
console.log(`Deploying to Cloudflare Pages project '${projectName}'…`);
|
|
151
153
|
// Wrangler resolves functions/ relative to cwd (not the deploy path arg),
|
|
152
154
|
// so run it from outputDir. The `.wrangler/` cache it creates lives
|
|
153
|
-
// inside the vault's .
|
|
155
|
+
// inside the vault's .vaults/cache/, which is already gitignored.
|
|
154
156
|
// --branch=main ensures Production-tagged deploys; --commit-dirty
|
|
155
157
|
// silences a noisy git warning.
|
|
156
158
|
await runWranglerInteractive(["pages", "deploy", ".", `--project-name=${projectName}`, "--branch=main", "--commit-dirty=true"], outputDir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/role.js
CHANGED
|
@@ -2,7 +2,9 @@ import { createInterface } from "node:readline/promises";
|
|
|
2
2
|
import { stdin, stdout } from "node:process";
|
|
3
3
|
import { hashPassword } from "../auth.js";
|
|
4
4
|
import { loadConfig, saveConfig } from "../config.js";
|
|
5
|
+
import { runMigrations } from "../migrate/run.js";
|
|
5
6
|
export async function roleAdd(name, vaultPath) {
|
|
7
|
+
await runMigrations(vaultPath);
|
|
6
8
|
if (!/^[a-z][a-z0-9_-]*$/i.test(name)) {
|
|
7
9
|
throw new Error(`Invalid role name '${name}'. Use letters, digits, '_' or '-' (must start with a letter).`);
|
|
8
10
|
}
|
|
@@ -23,6 +25,7 @@ export async function roleAdd(name, vaultPath) {
|
|
|
23
25
|
console.log(` Mark pages with 'role: ${name}' frontmatter or callouts with '> [!${name}]' to gate them.`);
|
|
24
26
|
}
|
|
25
27
|
export async function roleRemove(name, vaultPath) {
|
|
28
|
+
await runMigrations(vaultPath);
|
|
26
29
|
const cfg = await loadConfig(vaultPath, {});
|
|
27
30
|
if (!cfg.roles.includes(name)) {
|
|
28
31
|
throw new Error(`Role '${name}' is not configured (${cfg.roles.join(", ") || "empty"}).`);
|
|
@@ -43,6 +46,7 @@ export async function roleDemote(name, vaultPath) {
|
|
|
43
46
|
await reorderRole(name, vaultPath, -1);
|
|
44
47
|
}
|
|
45
48
|
async function reorderRole(name, vaultPath, delta) {
|
|
49
|
+
await runMigrations(vaultPath);
|
|
46
50
|
const cfg = await loadConfig(vaultPath, {});
|
|
47
51
|
const roles = cfg.roles;
|
|
48
52
|
const i = roles.indexOf(name);
|
|
@@ -61,6 +65,7 @@ async function reorderRole(name, vaultPath, delta) {
|
|
|
61
65
|
console.log(` New order: ${roles.join(" < ")}`);
|
|
62
66
|
}
|
|
63
67
|
export async function roleList(vaultPath) {
|
|
68
|
+
await runMigrations(vaultPath);
|
|
64
69
|
const cfg = await loadConfig(vaultPath, {});
|
|
65
70
|
if (cfg.roles.length === 0) {
|
|
66
71
|
console.log("No roles configured. Run `vaults role add <name>` to add one.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role.js","sourceRoot":"","sources":["../../src/commands/role.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"role.js","sourceRoot":"","sources":["../../src/commands/role.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import {
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
3
|
import { readDotEnv, writeDotEnv } from "./dotenv.js";
|
|
4
4
|
import { warnSensitive } from "./sensitive.js";
|
|
5
5
|
const DEFAULT_CONFIG = {
|
|
6
6
|
imageQuality: 85,
|
|
7
7
|
maxFileBytes: 25 * 1024 * 1024,
|
|
8
8
|
roles: ["public"],
|
|
9
|
-
authType: "password",
|
|
10
9
|
rolePasswords: {},
|
|
11
10
|
};
|
|
12
|
-
|
|
11
|
+
// Resolved at call time so migrations get a chance to move the file
|
|
12
|
+
// before any read happens. See cli/src/paths.ts.
|
|
13
|
+
import { configPath } from "./paths.js";
|
|
13
14
|
// Env var names — same as the Wrangler secret names so the .env line you
|
|
14
15
|
// write is exactly what gets uploaded as the Cloudflare Pages secret.
|
|
15
16
|
const ENV_SESSION_SECRET = "SESSION_SECRET";
|
|
@@ -39,10 +40,13 @@ export async function loadConfig(vaultPath, overrides) {
|
|
|
39
40
|
const sessionFromEnv = process.env[ENV_SESSION_SECRET] || dotEnv[ENV_SESSION_SECRET];
|
|
40
41
|
if (sessionFromEnv)
|
|
41
42
|
merged.sessionSecret = sessionFromEnv;
|
|
42
|
-
if (merged.patreon) {
|
|
43
|
+
if (merged.oauth?.patreon) {
|
|
43
44
|
const patreonSecretFromEnv = process.env[ENV_PATREON_CLIENT_SECRET] || dotEnv[ENV_PATREON_CLIENT_SECRET];
|
|
44
45
|
if (patreonSecretFromEnv) {
|
|
45
|
-
merged.
|
|
46
|
+
merged.oauth = {
|
|
47
|
+
...merged.oauth,
|
|
48
|
+
patreon: { ...merged.oauth.patreon, clientSecret: patreonSecretFromEnv },
|
|
49
|
+
};
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
// Deep-clone the mutable fields so callers can mutate (push to roles,
|
|
@@ -51,8 +55,12 @@ export async function loadConfig(vaultPath, overrides) {
|
|
|
51
55
|
...merged,
|
|
52
56
|
roles: [...merged.roles],
|
|
53
57
|
rolePasswords: { ...merged.rolePasswords },
|
|
54
|
-
...(merged.
|
|
55
|
-
|
|
58
|
+
...(merged.oauth ? {
|
|
59
|
+
oauth: {
|
|
60
|
+
...(merged.oauth.patreon ? {
|
|
61
|
+
patreon: { ...merged.oauth.patreon, tiers: { ...(merged.oauth.patreon.tiers ?? {}) } },
|
|
62
|
+
} : {}),
|
|
63
|
+
},
|
|
56
64
|
} : {}),
|
|
57
65
|
};
|
|
58
66
|
}
|
|
@@ -73,21 +81,28 @@ export async function saveConfig(vaultPath, cfg) {
|
|
|
73
81
|
if (k === "sessionSecret")
|
|
74
82
|
continue; // → .env
|
|
75
83
|
const v = cfg[k];
|
|
76
|
-
if (k === "
|
|
77
|
-
const
|
|
78
|
-
|
|
84
|
+
if (k === "oauth" && v) {
|
|
85
|
+
const oauth = v;
|
|
86
|
+
const persistedOauth = {};
|
|
87
|
+
if (oauth?.patreon) {
|
|
88
|
+
const { clientSecret: _drop, ...rest } = oauth.patreon;
|
|
89
|
+
persistedOauth.patreon = rest;
|
|
90
|
+
}
|
|
91
|
+
out.oauth = persistedOauth;
|
|
79
92
|
continue;
|
|
80
93
|
}
|
|
81
94
|
if (deepEqual(v, DEFAULT_CONFIG[k]))
|
|
82
95
|
continue;
|
|
83
96
|
out[k] = v;
|
|
84
97
|
}
|
|
85
|
-
|
|
98
|
+
const cfgPath = configPath(vaultPath);
|
|
99
|
+
await mkdir(dirname(cfgPath), { recursive: true });
|
|
100
|
+
await writeFile(cfgPath, JSON.stringify(out, null, 2) + "\n");
|
|
86
101
|
// Mirror secrets to .env. Use null to delete keys that are no longer set
|
|
87
102
|
// so a user clearing Patreon doesn't leave a stray client secret behind.
|
|
88
103
|
const envUpdates = {
|
|
89
104
|
[ENV_SESSION_SECRET]: cfg.sessionSecret || null,
|
|
90
|
-
[ENV_PATREON_CLIENT_SECRET]: cfg.patreon?.clientSecret || null,
|
|
105
|
+
[ENV_PATREON_CLIENT_SECRET]: cfg.oauth?.patreon?.clientSecret || null,
|
|
91
106
|
};
|
|
92
107
|
// Only touch .env if there's something to set/clear; avoids creating an
|
|
93
108
|
// empty .env in vaults that don't have any secrets.
|
|
@@ -108,7 +123,7 @@ function describeSecrets(cfg) {
|
|
|
108
123
|
const parts = [];
|
|
109
124
|
if (cfg.sessionSecret)
|
|
110
125
|
parts.push("the session-signing key");
|
|
111
|
-
if (cfg.patreon?.clientSecret)
|
|
126
|
+
if (cfg.oauth?.patreon?.clientSecret)
|
|
112
127
|
parts.push("a Patreon client secret");
|
|
113
128
|
if (parts.length === 0)
|
|
114
129
|
return null;
|
|
@@ -123,7 +138,7 @@ export async function saveSessionSecret(vaultPath, secret) {
|
|
|
123
138
|
}
|
|
124
139
|
async function readFileConfig(vaultPath) {
|
|
125
140
|
try {
|
|
126
|
-
const raw = await readFile(
|
|
141
|
+
const raw = await readFile(configPath(vaultPath), "utf8");
|
|
127
142
|
return JSON.parse(raw);
|
|
128
143
|
}
|
|
129
144
|
catch {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/escape.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Canonical HTML-escape helpers shared across the CLI.
|
|
2
|
+
//
|
|
3
|
+
// `htmlEscape` covers all five characters (& < > " ') for both text-content
|
|
4
|
+
// and attribute-value contexts; that strict superset is correct everywhere
|
|
5
|
+
// HTML is being assembled by string concatenation. `htmlAttr` is provided for
|
|
6
|
+
// the few callers that still want attribute-only escaping (& " <), which is
|
|
7
|
+
// strictly narrower; prefer `htmlEscape` unless you have a reason.
|
|
8
|
+
//
|
|
9
|
+
// Re-exported from `cli/src/render/handlers/types.ts` (the canonical name
|
|
10
|
+
// handlers see); existing imports there keep working.
|
|
11
|
+
const HTML_ESCAPE = {
|
|
12
|
+
"&": "&",
|
|
13
|
+
"<": "<",
|
|
14
|
+
">": ">",
|
|
15
|
+
'"': """,
|
|
16
|
+
"'": "'",
|
|
17
|
+
};
|
|
18
|
+
export function htmlEscape(s) {
|
|
19
|
+
return s.replace(/[&<>"']/g, (c) => HTML_ESCAPE[c]);
|
|
20
|
+
}
|
|
21
|
+
export function htmlAttr(s) {
|
|
22
|
+
return s.replace(/[&<>"]/g, (c) => HTML_ESCAPE[c]);
|
|
23
|
+
}
|
|
24
|
+
/** Escape every regex metacharacter so the result is safe to use as a
|
|
25
|
+
* literal-match needle inside a RegExp constructor. */
|
|
26
|
+
export function escapeRegex(s) {
|
|
27
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=escape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape.js","sourceRoot":"","sources":["../src/escape.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,mEAAmE;AACnE,EAAE;AACF,0EAA0E;AAC1E,sDAAsD;AAEtD,MAAM,WAAW,GAA2B;IAC1C,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,OAAO;CACb,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,CAAS;IAChC,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC;AACtD,CAAC;AAED;wDACwD;AACxD,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}
|
package/dist/favicon.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { join, isAbsolute } from "node:path";
|
|
3
3
|
import sharp from "sharp";
|
|
4
|
+
import { htmlEscape, htmlAttr } from "./escape.js";
|
|
4
5
|
const ICON_SIZE = 32;
|
|
5
6
|
/**
|
|
6
7
|
* Render the favicon for a vault to an ICO buffer. If the user pointed
|
|
@@ -24,45 +25,11 @@ async function renderDefaultIcon(letter, bg, accent) {
|
|
|
24
25
|
// Round-cornered square with a single letter centred. Embedded as an
|
|
25
26
|
// SVG so sharp rasterises it cleanly at the target size.
|
|
26
27
|
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
27
|
-
<rect width="32" height="32" rx="5" fill="${
|
|
28
|
+
<rect width="32" height="32" rx="5" fill="${htmlAttr(bg)}"/>
|
|
28
29
|
<text x="16" y="22" font-family="Iowan Old Style, Palatino Linotype, Georgia, serif"
|
|
29
30
|
font-size="22" font-weight="700" text-anchor="middle"
|
|
30
|
-
fill="${
|
|
31
|
+
fill="${htmlAttr(accent)}">${htmlEscape(letter)}</text>
|
|
31
32
|
</svg>`;
|
|
32
33
|
return sharp(Buffer.from(svg)).resize(ICON_SIZE, ICON_SIZE).png().toBuffer();
|
|
33
34
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Wrap a PNG buffer in an ICO container. Modern browsers accept PNG-in-ICO
|
|
36
|
-
* for any size; the dirent's width/height bytes are advisory.
|
|
37
|
-
*
|
|
38
|
-
* Pick black or white as the letter colour against `accent` so the icon
|
|
39
|
-
* stays readable for whatever colour the user picked. Uses W3C relative
|
|
40
|
-
* luminance.
|
|
41
|
-
*/
|
|
42
|
-
function bestForeground(accent) {
|
|
43
|
-
const rgb = parseColor(accent);
|
|
44
|
-
if (!rgb)
|
|
45
|
-
return "#ffffff";
|
|
46
|
-
const lin = (c) => {
|
|
47
|
-
const s = c / 255;
|
|
48
|
-
return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
|
|
49
|
-
};
|
|
50
|
-
const L = 0.2126 * lin(rgb[0]) + 0.7152 * lin(rgb[1]) + 0.0722 * lin(rgb[2]);
|
|
51
|
-
return L > 0.5 ? "#1d1a17" : "#ffffff";
|
|
52
|
-
}
|
|
53
|
-
function parseColor(s) {
|
|
54
|
-
const hex = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(s.trim());
|
|
55
|
-
if (!hex)
|
|
56
|
-
return null;
|
|
57
|
-
let h = hex[1];
|
|
58
|
-
if (h.length === 3)
|
|
59
|
-
h = h.split("").map((c) => c + c).join("");
|
|
60
|
-
return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
|
|
61
|
-
}
|
|
62
|
-
function escAttr(s) {
|
|
63
|
-
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
64
|
-
}
|
|
65
|
-
function escText(s) {
|
|
66
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
67
|
-
}
|
|
68
35
|
//# sourceMappingURL=favicon.js.map
|
package/dist/favicon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"favicon.js","sourceRoot":"","sources":["../src/favicon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"favicon.js","sourceRoot":"","sources":["../src/favicon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAMlC;IACC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW;QAC1B,CAAC,CAAC,MAAM,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC;QACzD,CAAC,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACjF,yDAAyD;IACzD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,WAAmB;IACnE,MAAM,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;AACvF,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,MAAc,EAAE,EAAU,EAAE,MAAc;IACzE,qEAAqE;IACrE,yDAAyD;IACzD,MAAM,GAAG,GAAG;8CACgC,QAAQ,CAAC,EAAE,CAAC;;;gBAG1C,QAAQ,CAAC,MAAM,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC;OAChD,CAAC;IACN,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Build helper: bundle the Foundry-side importer scripts into a single
|
|
2
|
+
// ESM file plus a sidecar version manifest. The bundle is served by
|
|
3
|
+
// every deploy at `_foundry/importer.js` and `_foundry/version.json`.
|
|
4
|
+
//
|
|
5
|
+
// The Foundry module fetches the bundle, hash-checks against its
|
|
6
|
+
// trust cache, evaluates it, and calls runSync / runRemove against a
|
|
7
|
+
// host it constructs. The version manifest carries `{ version, sha256 }`
|
|
8
|
+
// so the host can detect skew before evaluating.
|
|
9
|
+
import { build } from "esbuild";
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
12
|
+
import { dirname, join, resolve } from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { CLI_VERSION } from "./version.js";
|
|
15
|
+
const ENTRY_RELATIVE_TO_REPO = "foundry/scripts/importer-entry.mjs";
|
|
16
|
+
/** Locate the Foundry-side entry point. The CLI is published from `cli/`
|
|
17
|
+
* but runs against the monorepo checkout during dev / `vaults build` —
|
|
18
|
+
* walk up from this file until we find the foundry/ sibling. */
|
|
19
|
+
function resolveEntry() {
|
|
20
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
// dev: cli/src/ → cli → vaults/ → vaults/foundry/scripts/importer-entry.mjs
|
|
22
|
+
// installed: dist/ → cli → vaults/ → vaults/foundry/scripts/importer-entry.mjs (same)
|
|
23
|
+
return resolve(here, "..", "..", ENTRY_RELATIVE_TO_REPO);
|
|
24
|
+
}
|
|
25
|
+
async function bundleImporter() {
|
|
26
|
+
const entry = resolveEntry();
|
|
27
|
+
const result = await build({
|
|
28
|
+
entryPoints: [entry],
|
|
29
|
+
bundle: true,
|
|
30
|
+
format: "esm",
|
|
31
|
+
platform: "browser",
|
|
32
|
+
target: "es2022",
|
|
33
|
+
write: false,
|
|
34
|
+
// Foundry globals are present at runtime; esbuild treats them as
|
|
35
|
+
// externals automatically because they're not imported. No need to
|
|
36
|
+
// mark anything as external explicitly.
|
|
37
|
+
minify: false,
|
|
38
|
+
sourcemap: false,
|
|
39
|
+
legalComments: "none",
|
|
40
|
+
});
|
|
41
|
+
if (result.outputFiles.length !== 1) {
|
|
42
|
+
throw new Error(`expected 1 bundle output, got ${result.outputFiles.length}`);
|
|
43
|
+
}
|
|
44
|
+
const source = result.outputFiles[0].text;
|
|
45
|
+
const sha256 = createHash("sha256").update(source).digest("hex");
|
|
46
|
+
return { source, sha256 };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Write `_foundry/importer.js` + `_foundry/version.json` into the deploy.
|
|
50
|
+
* Called from build.ts after the variant outputs are in place — the
|
|
51
|
+
* bundle is a shared root-level asset (not per-variant), since it has
|
|
52
|
+
* no role-gated content.
|
|
53
|
+
*/
|
|
54
|
+
export async function writeFoundryImporter(outputDir) {
|
|
55
|
+
const { source, sha256 } = await bundleImporter();
|
|
56
|
+
const dir = join(outputDir, "_foundry");
|
|
57
|
+
await mkdir(dir, { recursive: true });
|
|
58
|
+
await writeFile(join(dir, "importer.js"), source);
|
|
59
|
+
await writeFile(join(dir, "version.json"), JSON.stringify({ version: CLI_VERSION, sha256 }, null, 2));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=foundry-importer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundry-importer.js","sourceRoot":"","sources":["../src/foundry-importer.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,oEAAoE;AACpE,sEAAsE;AACtE,EAAE;AACF,iEAAiE;AACjE,qEAAqE;AACrE,yEAAyE;AACzE,iDAAiD;AAEjD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,sBAAsB,GAAG,oCAAoC,CAAC;AASpE;;iEAEiE;AACjE,SAAS,YAAY;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,4EAA4E;IAC5E,sFAAsF;IACtF,OAAO,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,sBAAsB,CAAC,CAAC;AAC3D,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC;QACzB,WAAW,EAAE,CAAC,KAAK,CAAC;QACpB,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,SAAS;QACnB,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,KAAK;QACZ,iEAAiE;QACjE,mEAAmE;QACnE,wCAAwC;QACxC,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,KAAK;QAChB,aAAa,EAAE,MAAM;KACtB,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC;IAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,SAAiB;IAC1D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,cAAc,EAAE,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACxC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,SAAS,CACb,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EACzB,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAC1D,CAAC;AACJ,CAAC"}
|
package/dist/images.js
CHANGED
|
@@ -14,34 +14,4 @@ export async function compressImage(absolutePath, vaultRelPath, quality) {
|
|
|
14
14
|
const outputPath = vaultRelPath.replace(COMPRESSIBLE_EXT_RE, ".webp");
|
|
15
15
|
return { body, contentType: "image/webp", outputPath };
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Best-effort content-type lookup by extension. Falls back to octet-stream.
|
|
19
|
-
*/
|
|
20
|
-
export function contentTypeFor(path) {
|
|
21
|
-
const ext = path.split(".").pop()?.toLowerCase() ?? "";
|
|
22
|
-
const map = {
|
|
23
|
-
md: "text/markdown; charset=utf-8",
|
|
24
|
-
markdown: "text/markdown; charset=utf-8",
|
|
25
|
-
txt: "text/plain; charset=utf-8",
|
|
26
|
-
json: "application/json",
|
|
27
|
-
yaml: "application/yaml",
|
|
28
|
-
yml: "application/yaml",
|
|
29
|
-
html: "text/html; charset=utf-8",
|
|
30
|
-
css: "text/css; charset=utf-8",
|
|
31
|
-
png: "image/png",
|
|
32
|
-
jpg: "image/jpeg",
|
|
33
|
-
jpeg: "image/jpeg",
|
|
34
|
-
webp: "image/webp",
|
|
35
|
-
gif: "image/gif",
|
|
36
|
-
svg: "image/svg+xml",
|
|
37
|
-
avif: "image/avif",
|
|
38
|
-
mp3: "audio/mpeg",
|
|
39
|
-
wav: "audio/wav",
|
|
40
|
-
ogg: "audio/ogg",
|
|
41
|
-
m4a: "audio/mp4",
|
|
42
|
-
mp4: "video/mp4",
|
|
43
|
-
pdf: "application/pdf",
|
|
44
|
-
};
|
|
45
|
-
return map[ext] ?? "application/octet-stream";
|
|
46
|
-
}
|
|
47
17
|
//# sourceMappingURL=images.js.map
|
package/dist/images.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"images.js","sourceRoot":"","sources":["../src/images.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,mBAAmB,GAAG,qCAAqC,CAAC;AASzE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,YAAoB,EAAE,YAAoB,EAAE,OAAe;IAC7F,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;SACtD,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;SACjB,QAAQ,EAAE,CAAC;IAEd,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACtE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AACzD,CAAC
|
|
1
|
+
{"version":3,"file":"images.js","sourceRoot":"","sources":["../src/images.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,mBAAmB,GAAG,qCAAqC,CAAC;AASzE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,YAAoB,EAAE,YAAoB,EAAE,OAAe;IAC7F,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;SACtD,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;SACjB,QAAQ,EAAE,CAAC;IAEd,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACtE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AACzD,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,8 @@ import { init } from "./commands/init.js";
|
|
|
7
7
|
import { password } from "./commands/password.js";
|
|
8
8
|
import { roleAdd, roleDemote, roleList, rolePromote, roleRemove } from "./commands/role.js";
|
|
9
9
|
import { patreonClear, patreonConfigure, patreonLink, patreonStatus, patreonUnlink } from "./commands/patreon.js";
|
|
10
|
+
import { listMigrations, runMigrations } from "./migrate/run.js";
|
|
11
|
+
import { CLI_VERSION } from "./version.js";
|
|
10
12
|
const program = new Command();
|
|
11
13
|
// Default vault path: honour $VAULT_PATH first so users can drop
|
|
12
14
|
// `export VAULT_PATH=~/Documents/MyVault` in their shell rc and not pass it
|
|
@@ -15,7 +17,7 @@ const VAULT_PATH_DEFAULT = process.env.VAULT_PATH ?? process.cwd();
|
|
|
15
17
|
program
|
|
16
18
|
.name("vaults")
|
|
17
19
|
.description("Sync an Obsidian vault to a Cloudflare-hosted wiki")
|
|
18
|
-
.version(
|
|
20
|
+
.version(CLI_VERSION);
|
|
19
21
|
const role = program
|
|
20
22
|
.command("role")
|
|
21
23
|
.description("Manage roles (access tiers) in the vault");
|
|
@@ -95,7 +97,7 @@ program
|
|
|
95
97
|
.argument("[vault-path]", "Path to the Obsidian vault", VAULT_PATH_DEFAULT)
|
|
96
98
|
.action(async (role, vaultPath) => {
|
|
97
99
|
try {
|
|
98
|
-
await password(vaultPath, role
|
|
100
|
+
await password(vaultPath, role);
|
|
99
101
|
}
|
|
100
102
|
catch (err) {
|
|
101
103
|
console.error(err instanceof Error ? err.message : err);
|
|
@@ -183,7 +185,7 @@ program
|
|
|
183
185
|
.command("build")
|
|
184
186
|
.description("Render the vault to a local output directory")
|
|
185
187
|
.argument("[vault-path]", "Path to the Obsidian vault", VAULT_PATH_DEFAULT)
|
|
186
|
-
.option("-o, --output <dir>", "Output directory (default: <vault>/.
|
|
188
|
+
.option("-o, --output <dir>", "Output directory (default: <vault>/.vaults/cache/rendered)")
|
|
187
189
|
.option("-q, --image-quality <n>", "WebP image quality (0 = no compression)", (v) => parseInt(v, 10))
|
|
188
190
|
.option("-n, --vault-name <name>", "Display name for the vault", "Vault")
|
|
189
191
|
.option("--all-warnings", "Print every page with warnings instead of truncating at 20")
|
|
@@ -192,11 +194,42 @@ program
|
|
|
192
194
|
.command("preview")
|
|
193
195
|
.description("Render the vault and serve it locally via `wrangler pages dev` (Functions run)")
|
|
194
196
|
.argument("[vault-path]", "Path to the Obsidian vault", VAULT_PATH_DEFAULT)
|
|
195
|
-
.option("-o, --output <dir>", "Output directory (default: <vault>/.
|
|
197
|
+
.option("-o, --output <dir>", "Output directory (default: <vault>/.vaults/cache/rendered)")
|
|
196
198
|
.option("-p, --port <n>", "Port for the preview server", (v) => parseInt(v, 10), 4173)
|
|
197
199
|
.option("-q, --image-quality <n>", "WebP image quality (0 = no compression)", (v) => parseInt(v, 10))
|
|
198
200
|
.option("-n, --vault-name <name>", "Display name for the vault", "Vault")
|
|
199
201
|
.action(wrap(preview));
|
|
202
|
+
program
|
|
203
|
+
.command("migrate")
|
|
204
|
+
.description("Run pending vault layout / schema migrations")
|
|
205
|
+
.argument("[vault-path]", "Path to the Obsidian vault", VAULT_PATH_DEFAULT)
|
|
206
|
+
.option("--dry-run", "Show what would migrate without changing anything")
|
|
207
|
+
.option("--only <id>", "Run only the migration with this id")
|
|
208
|
+
.option("--list", "List all known migrations and exit")
|
|
209
|
+
.action(async (vaultPath, opts) => {
|
|
210
|
+
try {
|
|
211
|
+
if (opts.list) {
|
|
212
|
+
for (const m of listMigrations()) {
|
|
213
|
+
console.log(` ${m.id}\n ${m.description}`);
|
|
214
|
+
}
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const result = await runMigrations(vaultPath, { dryRun: opts.dryRun, ...(opts.only ? { only: opts.only } : {}) });
|
|
218
|
+
if (result.applied.length === 0) {
|
|
219
|
+
console.log("No pending migrations.");
|
|
220
|
+
}
|
|
221
|
+
else if (opts.dryRun) {
|
|
222
|
+
console.log(`Would apply ${result.applied.length} migration(s).`);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
console.log(`Applied ${result.applied.length} migration(s).`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
console.error(err instanceof Error ? err.message : err);
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
200
233
|
program
|
|
201
234
|
.command("push")
|
|
202
235
|
.description("Render and deploy the vault to Cloudflare Pages")
|