2026-05-14 08:36:44 +00:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
// Copy the three plugin artifacts (main.js, manifest.json, styles.css)
|
|
|
|
|
// into the vault's plugin folder. Replaces a symlink-based setup that
|
|
|
|
|
// Obsidian Sync was indexing slowly.
|
|
|
|
|
//
|
|
|
|
|
// Configure the destination once:
|
|
|
|
|
// - Either set STASHPAD_DEPLOY in your environment.
|
|
|
|
|
// - Or create a `.deploy-target` file at the project root containing
|
|
|
|
|
// the absolute path of the vault plugin folder, e.g.:
|
|
|
|
|
// /Users/you/Vault/.obsidian/plugins/stashpad
|
|
|
|
|
// The file is gitignored.
|
|
|
|
|
//
|
|
|
|
|
// Usage:
|
|
|
|
|
// npm run deploy — build + copy
|
|
|
|
|
// npm run deploy:files — copy only (no build)
|
|
|
|
|
|
|
|
|
|
import { existsSync, readFileSync, copyFileSync, mkdirSync, statSync } from "node:fs";
|
|
|
|
|
import { dirname, join, resolve } from "node:path";
|
|
|
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
|
|
|
|
|
|
// Use fileURLToPath so spaces (and other URL-encoded chars) in the
|
|
|
|
|
// project path don't break the resolved filesystem path.
|
|
|
|
|
const ROOT = resolve(fileURLToPath(new URL("..", import.meta.url)));
|
|
|
|
|
const ARTIFACTS = ["main.js", "manifest.json", "styles.css"];
|
|
|
|
|
|
2026-06-14 07:35:19 +00:00
|
|
|
function resolveTargets() {
|
|
|
|
|
// Multiple targets supported: STASHPAD_DEPLOY or `.deploy-target` may list ONE
|
|
|
|
|
// PATH PER LINE (blank lines + `#` comments ignored). EVERY target is updated on
|
|
|
|
|
// each deploy — keep the Plugin Test vault and the Claude Dev Vault in sync so
|
|
|
|
|
// live testing never runs a stale build.
|
|
|
|
|
const fromText = (raw) => raw.split(/\r?\n/).map((l) => l.trim()).filter((l) => l && !l.startsWith("#")).map((l) => resolve(l));
|
2026-05-14 08:36:44 +00:00
|
|
|
const envTarget = process.env.STASHPAD_DEPLOY?.trim();
|
2026-06-14 07:35:19 +00:00
|
|
|
if (envTarget) return fromText(envTarget);
|
2026-05-14 08:36:44 +00:00
|
|
|
const cfgPath = join(ROOT, ".deploy-target");
|
|
|
|
|
if (existsSync(cfgPath)) {
|
2026-06-14 07:35:19 +00:00
|
|
|
const targets = fromText(readFileSync(cfgPath, "utf8"));
|
|
|
|
|
if (targets.length) return targets;
|
2026-05-14 08:36:44 +00:00
|
|
|
}
|
2026-06-14 07:35:19 +00:00
|
|
|
return [];
|
2026-05-14 08:36:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fail(msg) {
|
|
|
|
|
console.error(`\n[deploy] ${msg}\n`);
|
|
|
|
|
process.exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-14 07:35:19 +00:00
|
|
|
const targets = resolveTargets();
|
|
|
|
|
if (targets.length === 0) {
|
2026-05-14 08:36:44 +00:00
|
|
|
fail(
|
|
|
|
|
"No deploy target configured. Set STASHPAD_DEPLOY env var or create a\n" +
|
2026-06-14 07:35:19 +00:00
|
|
|
".deploy-target file at the project root with one destination path per line.\n" +
|
2026-05-14 08:36:44 +00:00
|
|
|
"Example: /Users/you/MyVault/.obsidian/plugins/stashpad",
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-14 07:35:19 +00:00
|
|
|
let totalCopied = 0;
|
|
|
|
|
const allMissing = new Set();
|
|
|
|
|
for (const target of targets) {
|
|
|
|
|
const targetParent = dirname(target);
|
|
|
|
|
if (!existsSync(target)) {
|
|
|
|
|
try { mkdirSync(target, { recursive: true }); }
|
|
|
|
|
catch (e) { fail(`Couldn't create destination folder: ${target}\n${e.message}`); }
|
2026-05-14 08:36:44 +00:00
|
|
|
}
|
2026-06-14 07:35:19 +00:00
|
|
|
if (!existsSync(targetParent)) fail(`Parent of destination doesn't exist: ${targetParent}`);
|
2026-05-14 08:36:44 +00:00
|
|
|
|
2026-06-14 07:35:19 +00:00
|
|
|
let copied = 0;
|
|
|
|
|
for (const name of ARTIFACTS) {
|
|
|
|
|
const src = join(ROOT, name);
|
|
|
|
|
if (!existsSync(src)) { allMissing.add(name); continue; }
|
|
|
|
|
const dst = join(target, name);
|
|
|
|
|
copyFileSync(src, dst);
|
|
|
|
|
const sz = statSync(dst).size;
|
|
|
|
|
console.log(`[deploy] ${name.padEnd(14)} → ${dst} (${sz} bytes)`);
|
|
|
|
|
copied++;
|
|
|
|
|
}
|
|
|
|
|
console.log(`[deploy] copied ${copied}/${ARTIFACTS.length} → ${target}`);
|
|
|
|
|
totalCopied += copied;
|
2026-05-14 08:36:44 +00:00
|
|
|
}
|
2026-06-14 07:35:19 +00:00
|
|
|
if (allMissing.size) {
|
|
|
|
|
console.warn(`[deploy] WARNING: missing artifacts: ${[...allMissing].join(", ")} — did you build?`);
|
2026-05-14 08:36:44 +00:00
|
|
|
}
|
2026-06-14 07:35:19 +00:00
|
|
|
console.log(`[deploy] done — ${targets.length} target${targets.length === 1 ? "" : "s"}, ${totalCopied} file copies`);
|