obsidian-launcher 0.2.3 → 0.2.5
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/dist/cli.cjs +20 -15
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +19 -14
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/bin/env node
|
|
2
|
-
"use strict"; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
"use strict"; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
3
3
|
|
|
4
4
|
var _chunk2DK4DOJUcjs = require('./chunk-2DK4DOJU.cjs');
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash);
|
|
|
9
9
|
var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
|
|
10
10
|
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
11
11
|
var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_promises);
|
|
12
|
-
function parsePlugins(plugins) {
|
|
12
|
+
function parsePlugins(plugins = []) {
|
|
13
13
|
return plugins.map((p) => {
|
|
14
14
|
if (p.startsWith("id:")) {
|
|
15
15
|
return { id: p.slice(3) };
|
|
@@ -20,7 +20,7 @@ function parsePlugins(plugins) {
|
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
function parseThemes(themes) {
|
|
23
|
+
function parseThemes(themes = []) {
|
|
24
24
|
return themes.map((t, i) => {
|
|
25
25
|
let result;
|
|
26
26
|
if (t.startsWith("name:")) {
|
|
@@ -43,13 +43,14 @@ function watchFiles(files, func, options) {
|
|
|
43
43
|
_fs2.default.watchFile(file, { interval: options.interval, persistent: options.persistent }, debouncedFunc);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
+
var collectOpt = (curr, prev) => [..._nullishCoalesce(prev, () => ( [])), curr];
|
|
46
47
|
var versionOptionArgs = [
|
|
47
48
|
"-v, --version <version>",
|
|
48
49
|
"Obsidian version to run",
|
|
49
50
|
"latest"
|
|
50
51
|
];
|
|
51
|
-
var
|
|
52
|
-
"--installer
|
|
52
|
+
var installerOptionArgs = [
|
|
53
|
+
"-i, --installer <version>",
|
|
53
54
|
"Obsidian installer version to run",
|
|
54
55
|
"latest"
|
|
55
56
|
];
|
|
@@ -60,17 +61,15 @@ var cacheOptionArgs = [
|
|
|
60
61
|
var pluginOptionArgs = [
|
|
61
62
|
"-p, --plugin <plugin>",
|
|
62
63
|
`Plugin to install. Format: "<path>" or "repo:<github-repo>" or "id:<community-id>". Can be repeated.`,
|
|
63
|
-
|
|
64
|
-
[]
|
|
64
|
+
collectOpt
|
|
65
65
|
];
|
|
66
66
|
var themeOptionArgs = [
|
|
67
67
|
"-t, --theme <plugin>",
|
|
68
68
|
`Theme to install. Format: "<path>" or "repo:<github-repo>" or "name:<community-name>". Can be repeated but only last will be enabled.`,
|
|
69
|
-
|
|
70
|
-
[]
|
|
69
|
+
collectOpt
|
|
71
70
|
];
|
|
72
71
|
var program = new (0, _commander.Command)("obsidian-launcher");
|
|
73
|
-
program.command("download").description("Download Obsidian to the cache").option(...cacheOptionArgs).option(...versionOptionArgs).option(...
|
|
72
|
+
program.command("download").description("Download Obsidian to the cache").option(...cacheOptionArgs).option(...versionOptionArgs).option(...installerOptionArgs).action(async (opts) => {
|
|
74
73
|
const launcher = new (0, _chunk2DK4DOJUcjs.ObsidianLauncher)({ cacheDir: opts.cache });
|
|
75
74
|
const [appVersion, installerVersion] = await launcher.resolveVersions(opts.version, opts.installerVersion);
|
|
76
75
|
const installerPath = await launcher.downloadInstaller(installerVersion);
|
|
@@ -86,7 +85,7 @@ program.command("install").description("Install plugins and themes into an Obsid
|
|
|
86
85
|
});
|
|
87
86
|
program.command("launch").summary("Download and launch Obsidian").description(
|
|
88
87
|
"Download and launch Obsidian, opening the specified vault. The Obsidian instance will have a sandboxed configuration directory."
|
|
89
|
-
).argument("[vault]", "Vault to open").option(...cacheOptionArgs).option(...versionOptionArgs).option(...
|
|
88
|
+
).argument("[vault]", "Vault to open").option(...cacheOptionArgs).option(...versionOptionArgs).option(...installerOptionArgs).option(...pluginOptionArgs).option(...themeOptionArgs).option("--copy", "Copy the vault first").action(async (vault, opts) => {
|
|
90
89
|
const launcher = new (0, _chunk2DK4DOJUcjs.ObsidianLauncher)({ cacheDir: opts.cache });
|
|
91
90
|
const { proc, configDir, vault: vaultCopy } = await launcher.launch({
|
|
92
91
|
appVersion: opts.version,
|
|
@@ -105,15 +104,16 @@ program.command("launch").summary("Download and launch Obsidian").description(
|
|
|
105
104
|
});
|
|
106
105
|
program.command("watch").summary("Launch Obsidian and watch for changes to plugins and themes").description(
|
|
107
106
|
'Downloads Obsidian and opens a vault, then watches for changes to plugins and themes.\n\nTakes the same arguments as the "launch" command but watches for changes to any local plugins or themes and updates the copies in the vault. Automatically installs the "pjeby/hot-reload" so plugins will hot reload as they are updated.'
|
|
108
|
-
).argument("[vault]", "Vault to open").option(...cacheOptionArgs).option(...versionOptionArgs).option(...
|
|
107
|
+
).argument("[vault]", "Vault to open").option(...cacheOptionArgs).option(...versionOptionArgs).option(...installerOptionArgs).option(...pluginOptionArgs).option(...themeOptionArgs).option("--copy", "Copy the vault first").action(async (vault, opts) => {
|
|
109
108
|
const launcher = new (0, _chunk2DK4DOJUcjs.ObsidianLauncher)({ cacheDir: opts.cache });
|
|
110
109
|
const plugins = await launcher.downloadPlugins(parsePlugins(opts.plugin));
|
|
111
110
|
const themes = await launcher.downloadThemes(parseThemes(opts.theme));
|
|
111
|
+
const copy = _nullishCoalesce(opts.copy, () => ( false));
|
|
112
112
|
const launchArgs = {
|
|
113
113
|
appVersion: opts.version,
|
|
114
114
|
installerVersion: opts.installerVersion,
|
|
115
115
|
vault,
|
|
116
|
-
copy
|
|
116
|
+
copy,
|
|
117
117
|
plugins,
|
|
118
118
|
themes
|
|
119
119
|
};
|
|
@@ -125,6 +125,9 @@ program.command("watch").summary("Launch Obsidian and watch for changes to plugi
|
|
|
125
125
|
stdio: "pipe"
|
|
126
126
|
}
|
|
127
127
|
});
|
|
128
|
+
if (copy) {
|
|
129
|
+
console.log(`Vault copied to ${vaultCopy}`);
|
|
130
|
+
}
|
|
128
131
|
proc.stdout.on("data", (data) => console.log(data.toString()));
|
|
129
132
|
proc.stderr.on("data", (data) => console.log(data.toString()));
|
|
130
133
|
const procExit = new Promise((resolve) => proc.on("exit", (code) => resolve(_nullishCoalesce(code, () => ( -1)))));
|
|
@@ -164,7 +167,6 @@ program.command("watch").summary("Launch Obsidian and watch for changes to plugi
|
|
|
164
167
|
proc.kill("SIGTERM");
|
|
165
168
|
await procExit;
|
|
166
169
|
await _promises2.default.rm(configDir, { recursive: true, force: true });
|
|
167
|
-
await _promises2.default.rm(vaultCopy, { recursive: true, force: true });
|
|
168
170
|
process.exit(1);
|
|
169
171
|
};
|
|
170
172
|
process.on("SIGINT", cleanup);
|
|
@@ -190,5 +192,8 @@ program.command("create-versions-list").summary("Collect Obsidian version inform
|
|
|
190
192
|
_promises2.default.writeFile(dest, JSON.stringify(versionInfos, void 0, 4));
|
|
191
193
|
console.log(`Wrote updated version information to ${dest}`);
|
|
192
194
|
});
|
|
193
|
-
program.
|
|
195
|
+
program.parseAsync().catch((err) => {
|
|
196
|
+
console.log(_nullishCoalesce(_optionalChain([err, 'optionalAccess', _2 => _2.message]), () => ( err.toString())));
|
|
197
|
+
process.exit(1);
|
|
198
|
+
});
|
|
194
199
|
//# sourceMappingURL=cli.cjs.map
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/wdio-obsidian-service/wdio-obsidian-service/packages/obsidian-launcher/dist/cli.cjs","../src/cli.ts"],"names":[],"mappings":"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","file":"/home/runner/work/wdio-obsidian-service/wdio-obsidian-service/packages/obsidian-launcher/dist/cli.cjs","sourcesContent":[null,"#!/bin/env node\nimport { Command } from 'commander';\nimport _ from \"lodash\";\nimport { ObsidianLauncher } from \"./launcher.js\"\nimport { PluginEntry, ThemeEntry } from \"./types.js\";\nimport fs from \"fs\";\nimport path from \"path\"\nimport fsAsync from \"fs/promises\";\n\n\nfunction parsePlugins(plugins: string[]): PluginEntry[] {\n return plugins.map((p: string) => {\n if (p.startsWith(\"id:\")) {\n return {id: p.slice(3)}\n } else if (p.startsWith(\"repo:\")) {\n return {repo: p.slice(5)}\n } else {\n return {path: p}\n }\n })\n}\n\nfunction parseThemes(themes: string[]): ThemeEntry[] {\n return themes.map((t: string, i: number) => {\n let result: ThemeEntry\n if (t.startsWith(\"name:\")) {\n result = {name: t.slice(5)}\n } else if (t.startsWith(\"repo:\")) {\n result = {repo: t.slice(5)}\n } else {\n result = {path: t}\n }\n return {...result, enabled: i == themes.length - 1}\n })\n}\n\n/**\n * Watch a list of files, calls func whenever there's an update. Debounced files changes.\n */\nfunction watchFiles(\n files: string[],\n func: (curr: fs.Stats, prev: fs.Stats) => void,\n options: { interval: number, persistent: boolean, debounce: number },\n) {\n const debouncedFunc = _.debounce((curr: fs.Stats, prev: fs.Stats) => {\n if (curr.mtimeMs > prev.mtimeMs || (curr.mtimeMs == 0 && prev.mtimeMs != 0)) {\n func(curr, prev)\n }\n }, options.debounce);\n for (const file of files) {\n fs.watchFile(file, {interval: options.interval, persistent: options.persistent}, debouncedFunc);\n }\n}\n\nconst versionOptionArgs = [\n '-v, --version <version>',\n \"Obsidian version to run\",\n \"latest\",\n] as const\nconst installerVersionOptionArgs = [\n '--installer-version <version>',\n \"Obsidian installer version to run\",\n \"latest\",\n] as const\nconst cacheOptionArgs = [\n '-c, --cache <cache>',\n 'Directory to use as the download cache',\n] as const\nconst pluginOptionArgs = [\n '-p, --plugin <plugin>',\n `Plugin to install. Format: \"<path>\" or \"repo:<github-repo>\" or \"id:<community-id>\". Can be repeated.`,\n (curr: string, prev: string[]) => [...prev, curr], [] as string[],\n] as const\nconst themeOptionArgs = [\n '-t, --theme <plugin>',\n `Theme to install. Format: \"<path>\" or \"repo:<github-repo>\" or \"name:<community-name>\". Can be repeated but only last will be enabled.`,\n (curr: string, prev: string[]) => [...prev, curr], [] as string[],\n] as const\n\nconst program = new Command(\"obsidian-launcher\");\n\nprogram\n .command(\"download\")\n .description(\"Download Obsidian to the cache\")\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerVersionOptionArgs)\n .action(async (opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n const [appVersion, installerVersion] = await launcher.resolveVersions(opts.version, opts.installerVersion);\n const installerPath = await launcher.downloadInstaller(installerVersion);\n console.log(`Downloaded Obsidian installer to ${installerPath}`)\n const appPath = await launcher.downloadApp(appVersion);\n console.log(`Downloaded Obsidian app to ${appPath}`)\n })\n\nprogram\n .command(\"install\")\n .description(\"Install plugins and themes into an Obsidian vault\")\n .argument('<vault>', 'Vault to install into')\n .option(...cacheOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .action(async (vault, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n await launcher.installPlugins(vault, parsePlugins(opts.plugin));\n await launcher.installThemes(vault, parseThemes(opts.theme));\n console.log(`Installed plugins and themes into ${vault}`)\n })\n\n\nprogram\n .command(\"launch\")\n .summary(\"Download and launch Obsidian\")\n .description(\n \"Download and launch Obsidian, opening the specified vault. The Obsidian instance will have a sandboxed \" +\n \"configuration directory.\"\n )\n .argument('[vault]', 'Vault to open')\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerVersionOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .option('--copy', \"Copy the vault first\")\n .action(async (vault: string|undefined, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n const {proc, configDir, vault: vaultCopy} = await launcher.launch({\n appVersion: opts.version, installerVersion: opts.installerVersion,\n vault: vault,\n copy: opts.copy ?? false,\n plugins: parsePlugins(opts.plugin),\n themes: parseThemes(opts.theme),\n spawnOptions: {\n detached: true,\n stdio: 'ignore',\n }\n })\n proc.unref() // Allow node to exit and leave proc running\n console.log(`Launched obsidian ${opts.version}`)\n })\n\nprogram\n .command(\"watch\")\n .summary(\"Launch Obsidian and watch for changes to plugins and themes\")\n .description(\n \"Downloads Obsidian and opens a vault, then watches for changes to plugins and themes.\\n\" +\n \"\\n\" +\n 'Takes the same arguments as the \"launch\" command but watches for changes to any local plugins or themes and ' +\n 'updates the copies in the vault. Automatically installs the \"pjeby/hot-reload\" so plugins will hot reload ' +\n 'as they are updated.'\n )\n .argument('[vault]', 'Vault to open')\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerVersionOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .option('--copy', \"Copy the vault first\")\n .action(async (vault: string, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n // Normalize the plugins and themes\n const plugins = await launcher.downloadPlugins(parsePlugins(opts.plugin));\n const themes = await launcher.downloadThemes(parseThemes(opts.theme));\n const launchArgs = {\n appVersion: opts.version, installerVersion: opts.installerVersion,\n vault: vault,\n copy: opts.copy ?? false,\n plugins: plugins,\n themes: themes,\n } as const\n\n const {proc, configDir, vault: vaultCopy} = await launcher.launch({\n ...launchArgs,\n plugins: [...plugins, {repo: \"pjeby/hot-reload\"}],\n spawnOptions: {\n detached: false,\n stdio: \"pipe\",\n }\n })\n proc.stdout!.on('data', data => console.log(data.toString()));\n proc.stderr!.on('data', data => console.log(data.toString()));\n const procExit = new Promise<number>((resolve) => proc.on('exit', (code) => resolve(code ?? -1)));\n\n for (const plugin of plugins) {\n if (plugin.originalType == \"local\") {\n watchFiles(\n [\"manifest.json\", \"main.js\", \"styles.css\", \"data.json\"].map(f => path.join(plugin.path, f)),\n async () => {\n console.log(`Detected change to \"${plugin.id}\"`);\n try {\n await launcher.installPlugins(vaultCopy!, [plugin]);\n } catch (e) {\n console.error(`Failed to update plugin \"${plugin.id}\": ${e}`)\n }\n },\n {interval: 500, persistent: false, debounce: 1000},\n )\n }\n }\n for (const theme of themes) {\n if (theme.originalType == \"local\") {\n watchFiles(\n [\"manifest.json\", \"theme.css\"].map(f => path.join(theme.path, f)),\n async () => {\n console.log(`Detected change to \"${theme.name}\"`);\n try {\n await launcher.installThemes(vaultCopy!, [theme]);\n } catch (e) {\n console.error(`Failed to update theme \"${theme.name}\": ${e}`)\n }\n },\n {interval: 500, persistent: false, debounce: 1000},\n )\n }\n }\n\n const cleanup = async () => {\n proc.kill(\"SIGTERM\");\n await procExit;\n await fsAsync.rm(configDir, {recursive: true, force: true});\n await fsAsync.rm(vaultCopy!, {recursive: true, force: true});\n process.exit(1);\n }\n process.on('SIGINT', cleanup);\n process.on('exit', cleanup);\n\n console.log(\"Watching for changes to plugins and themes...\")\n await procExit;\n })\n\nprogram\n .command(\"create-versions-list\")\n .summary(\"Collect Obsidian version information into a single file\")\n .description(\n \"Collect Obsidian version information into a single file.\\n\" +\n \"\\n\" +\n \"This command is used to collect Obsidian version information in one place including download links, the \" +\n \"minimum installer version, and the internal Electron version for every Obsidian release and beta version. \" +\n \"This info is available and automatically kept up to date at \" +\n \"https://raw.githubusercontent.com/jesse-r-s-hines/wdio-obsidian-service/HEAD/obsidian-versions.json \" +\n \"but you can use this command to recreate the file manually if you want.\"\n )\n .argument('dest', 'Path to output. If it already exists, it will update the information instead of creating it from scratch.')\n .option(...cacheOptionArgs)\n .option('--max-instances <count>', \"Number of parallel Obsidian instances to launch when checking Electron versions\", \"1\")\n .action(async (dest, opts) => {\n let versionInfos: any;\n try {\n versionInfos = JSON.parse(await fsAsync.readFile(dest, \"utf-8\"))\n } catch {\n versionInfos = undefined;\n }\n const maxInstances = Number(opts.maxInstances)\n if (isNaN(maxInstances)) {\n throw Error(`Invalid number ${opts.maxInstances}`)\n }\n\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n versionInfos = await launcher.updateObsidianVersionInfos(versionInfos, { maxInstances });\n fsAsync.writeFile(dest, JSON.stringify(versionInfos, undefined, 4));\n console.log(`Wrote updated version information to ${dest}`)\n })\n\nprogram.parse();\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/wdio-obsidian-service/wdio-obsidian-service/packages/obsidian-launcher/dist/cli.cjs","../src/cli.ts"],"names":[],"mappings":"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","file":"/home/runner/work/wdio-obsidian-service/wdio-obsidian-service/packages/obsidian-launcher/dist/cli.cjs","sourcesContent":[null,"#!/bin/env node\nimport { Command } from 'commander';\nimport _ from \"lodash\";\nimport { ObsidianLauncher } from \"./launcher.js\"\nimport { PluginEntry, ThemeEntry } from \"./types.js\";\nimport fs from \"fs\";\nimport path from \"path\"\nimport fsAsync from \"fs/promises\";\n\n\nfunction parsePlugins(plugins: string[] = []): PluginEntry[] {\n return plugins.map((p: string) => {\n if (p.startsWith(\"id:\")) {\n return {id: p.slice(3)}\n } else if (p.startsWith(\"repo:\")) {\n return {repo: p.slice(5)}\n } else {\n return {path: p}\n }\n })\n}\n\nfunction parseThemes(themes: string[] = []): ThemeEntry[] {\n return themes.map((t: string, i: number) => {\n let result: ThemeEntry\n if (t.startsWith(\"name:\")) {\n result = {name: t.slice(5)}\n } else if (t.startsWith(\"repo:\")) {\n result = {repo: t.slice(5)}\n } else {\n result = {path: t}\n }\n return {...result, enabled: i == themes.length - 1}\n })\n}\n\n/**\n * Watch a list of files, calls func whenever there's an update. Debounced files changes.\n */\nfunction watchFiles(\n files: string[],\n func: (curr: fs.Stats, prev: fs.Stats) => void,\n options: { interval: number, persistent: boolean, debounce: number },\n) {\n const debouncedFunc = _.debounce((curr: fs.Stats, prev: fs.Stats) => {\n if (curr.mtimeMs > prev.mtimeMs || (curr.mtimeMs == 0 && prev.mtimeMs != 0)) {\n func(curr, prev)\n }\n }, options.debounce);\n for (const file of files) {\n fs.watchFile(file, {interval: options.interval, persistent: options.persistent}, debouncedFunc);\n }\n}\n\nconst collectOpt = (curr: string, prev?: string[]) => [...(prev ?? []), curr];\n\nconst versionOptionArgs = [\n '-v, --version <version>',\n \"Obsidian version to run\",\n \"latest\",\n] as const\nconst installerOptionArgs = [\n '-i, --installer <version>',\n \"Obsidian installer version to run\",\n \"latest\",\n] as const\nconst cacheOptionArgs = [\n '-c, --cache <cache>',\n 'Directory to use as the download cache',\n] as const\nconst pluginOptionArgs = [\n '-p, --plugin <plugin>',\n `Plugin to install. Format: \"<path>\" or \"repo:<github-repo>\" or \"id:<community-id>\". Can be repeated.`,\n collectOpt,\n] as const\nconst themeOptionArgs = [\n '-t, --theme <plugin>',\n `Theme to install. Format: \"<path>\" or \"repo:<github-repo>\" or \"name:<community-name>\". Can be repeated but only last will be enabled.`,\n collectOpt,\n] as const\n\nconst program = new Command(\"obsidian-launcher\");\n\nprogram\n .command(\"download\")\n .description(\"Download Obsidian to the cache\")\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerOptionArgs)\n .action(async (opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n const [appVersion, installerVersion] = await launcher.resolveVersions(opts.version, opts.installerVersion);\n const installerPath = await launcher.downloadInstaller(installerVersion);\n console.log(`Downloaded Obsidian installer to ${installerPath}`)\n const appPath = await launcher.downloadApp(appVersion);\n console.log(`Downloaded Obsidian app to ${appPath}`)\n })\n\nprogram\n .command(\"install\")\n .description(\"Install plugins and themes into an Obsidian vault\")\n .argument('<vault>', 'Vault to install into')\n .option(...cacheOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .action(async (vault, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n await launcher.installPlugins(vault, parsePlugins(opts.plugin));\n await launcher.installThemes(vault, parseThemes(opts.theme));\n console.log(`Installed plugins and themes into ${vault}`)\n })\n\n\nprogram\n .command(\"launch\")\n .summary(\"Download and launch Obsidian\")\n .description(\n \"Download and launch Obsidian, opening the specified vault. The Obsidian instance will have a sandboxed \" +\n \"configuration directory.\"\n )\n .argument('[vault]', 'Vault to open')\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .option('--copy', \"Copy the vault first\")\n .action(async (vault: string|undefined, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n const {proc, configDir, vault: vaultCopy} = await launcher.launch({\n appVersion: opts.version, installerVersion: opts.installerVersion,\n vault: vault,\n copy: opts.copy ?? false,\n plugins: parsePlugins(opts.plugin),\n themes: parseThemes(opts.theme),\n spawnOptions: {\n detached: true,\n stdio: 'ignore',\n }\n })\n proc.unref() // Allow node to exit and leave proc running\n console.log(`Launched obsidian ${opts.version}`)\n })\n\nprogram\n .command(\"watch\")\n .summary(\"Launch Obsidian and watch for changes to plugins and themes\")\n .description(\n \"Downloads Obsidian and opens a vault, then watches for changes to plugins and themes.\\n\" +\n \"\\n\" +\n 'Takes the same arguments as the \"launch\" command but watches for changes to any local plugins or themes and ' +\n 'updates the copies in the vault. Automatically installs the \"pjeby/hot-reload\" so plugins will hot reload ' +\n 'as they are updated.'\n )\n .argument('[vault]', 'Vault to open')\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .option('--copy', \"Copy the vault first\")\n .action(async (vault: string, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n // Normalize the plugins and themes\n const plugins = await launcher.downloadPlugins(parsePlugins(opts.plugin));\n const themes = await launcher.downloadThemes(parseThemes(opts.theme));\n const copy: boolean = opts.copy ?? false;\n const launchArgs = {\n appVersion: opts.version, installerVersion: opts.installerVersion,\n vault: vault,\n copy: copy,\n plugins: plugins,\n themes: themes,\n } as const\n\n const {proc, configDir, vault: vaultCopy} = await launcher.launch({\n ...launchArgs,\n plugins: [...plugins, {repo: \"pjeby/hot-reload\"}],\n spawnOptions: {\n detached: false,\n stdio: \"pipe\",\n }\n })\n if (copy) {\n console.log(`Vault copied to ${vaultCopy}`);\n }\n proc.stdout!.on('data', data => console.log(data.toString()));\n proc.stderr!.on('data', data => console.log(data.toString()));\n const procExit = new Promise<number>((resolve) => proc.on('exit', (code) => resolve(code ?? -1)));\n\n for (const plugin of plugins) {\n if (plugin.originalType == \"local\") {\n watchFiles(\n [\"manifest.json\", \"main.js\", \"styles.css\", \"data.json\"].map(f => path.join(plugin.path, f)),\n async () => {\n console.log(`Detected change to \"${plugin.id}\"`);\n try {\n await launcher.installPlugins(vaultCopy!, [plugin]);\n } catch (e) {\n console.error(`Failed to update plugin \"${plugin.id}\": ${e}`)\n }\n },\n {interval: 500, persistent: false, debounce: 1000},\n )\n }\n }\n for (const theme of themes) {\n if (theme.originalType == \"local\") {\n watchFiles(\n [\"manifest.json\", \"theme.css\"].map(f => path.join(theme.path, f)),\n async () => {\n console.log(`Detected change to \"${theme.name}\"`);\n try {\n await launcher.installThemes(vaultCopy!, [theme]);\n } catch (e) {\n console.error(`Failed to update theme \"${theme.name}\": ${e}`)\n }\n },\n {interval: 500, persistent: false, debounce: 1000},\n )\n }\n }\n\n const cleanup = async () => {\n proc.kill(\"SIGTERM\");\n await procExit;\n await fsAsync.rm(configDir, {recursive: true, force: true});\n process.exit(1);\n }\n process.on('SIGINT', cleanup);\n process.on('exit', cleanup);\n\n console.log(\"Watching for changes to plugins and themes...\")\n await procExit;\n })\n\nprogram\n .command(\"create-versions-list\")\n .summary(\"Collect Obsidian version information into a single file\")\n .description(\n \"Collect Obsidian version information into a single file.\\n\" +\n \"\\n\" +\n \"This command is used to collect Obsidian version information in one place including download links, the \" +\n \"minimum installer version, and the internal Electron version for every Obsidian release and beta version. \" +\n \"This info is available and automatically kept up to date at \" +\n \"https://raw.githubusercontent.com/jesse-r-s-hines/wdio-obsidian-service/HEAD/obsidian-versions.json \" +\n \"but you can use this command to recreate the file manually if you want.\"\n )\n .argument('dest', 'Path to output. If it already exists, it will update the information instead of creating it from scratch.')\n .option(...cacheOptionArgs)\n .option('--max-instances <count>', \"Number of parallel Obsidian instances to launch when checking Electron versions\", \"1\")\n .action(async (dest, opts) => {\n let versionInfos: any;\n try {\n versionInfos = JSON.parse(await fsAsync.readFile(dest, \"utf-8\"))\n } catch {\n versionInfos = undefined;\n }\n const maxInstances = Number(opts.maxInstances)\n if (isNaN(maxInstances)) {\n throw Error(`Invalid number ${opts.maxInstances}`)\n }\n\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n versionInfos = await launcher.updateObsidianVersionInfos(versionInfos, { maxInstances });\n fsAsync.writeFile(dest, JSON.stringify(versionInfos, undefined, 4));\n console.log(`Wrote updated version information to ${dest}`)\n })\n\nprogram\n .parseAsync()\n .catch((err) => {\n console.log(err?.message ?? err.toString())\n process.exit(1);\n });\n"]}
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import _ from "lodash";
|
|
|
9
9
|
import fs from "fs";
|
|
10
10
|
import path from "path";
|
|
11
11
|
import fsAsync from "fs/promises";
|
|
12
|
-
function parsePlugins(plugins) {
|
|
12
|
+
function parsePlugins(plugins = []) {
|
|
13
13
|
return plugins.map((p) => {
|
|
14
14
|
if (p.startsWith("id:")) {
|
|
15
15
|
return { id: p.slice(3) };
|
|
@@ -20,7 +20,7 @@ function parsePlugins(plugins) {
|
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
function parseThemes(themes) {
|
|
23
|
+
function parseThemes(themes = []) {
|
|
24
24
|
return themes.map((t, i) => {
|
|
25
25
|
let result;
|
|
26
26
|
if (t.startsWith("name:")) {
|
|
@@ -43,13 +43,14 @@ function watchFiles(files, func, options) {
|
|
|
43
43
|
fs.watchFile(file, { interval: options.interval, persistent: options.persistent }, debouncedFunc);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
+
var collectOpt = (curr, prev) => [...prev ?? [], curr];
|
|
46
47
|
var versionOptionArgs = [
|
|
47
48
|
"-v, --version <version>",
|
|
48
49
|
"Obsidian version to run",
|
|
49
50
|
"latest"
|
|
50
51
|
];
|
|
51
|
-
var
|
|
52
|
-
"--installer
|
|
52
|
+
var installerOptionArgs = [
|
|
53
|
+
"-i, --installer <version>",
|
|
53
54
|
"Obsidian installer version to run",
|
|
54
55
|
"latest"
|
|
55
56
|
];
|
|
@@ -60,17 +61,15 @@ var cacheOptionArgs = [
|
|
|
60
61
|
var pluginOptionArgs = [
|
|
61
62
|
"-p, --plugin <plugin>",
|
|
62
63
|
`Plugin to install. Format: "<path>" or "repo:<github-repo>" or "id:<community-id>". Can be repeated.`,
|
|
63
|
-
|
|
64
|
-
[]
|
|
64
|
+
collectOpt
|
|
65
65
|
];
|
|
66
66
|
var themeOptionArgs = [
|
|
67
67
|
"-t, --theme <plugin>",
|
|
68
68
|
`Theme to install. Format: "<path>" or "repo:<github-repo>" or "name:<community-name>". Can be repeated but only last will be enabled.`,
|
|
69
|
-
|
|
70
|
-
[]
|
|
69
|
+
collectOpt
|
|
71
70
|
];
|
|
72
71
|
var program = new Command("obsidian-launcher");
|
|
73
|
-
program.command("download").description("Download Obsidian to the cache").option(...cacheOptionArgs).option(...versionOptionArgs).option(...
|
|
72
|
+
program.command("download").description("Download Obsidian to the cache").option(...cacheOptionArgs).option(...versionOptionArgs).option(...installerOptionArgs).action(async (opts) => {
|
|
74
73
|
const launcher = new ObsidianLauncher({ cacheDir: opts.cache });
|
|
75
74
|
const [appVersion, installerVersion] = await launcher.resolveVersions(opts.version, opts.installerVersion);
|
|
76
75
|
const installerPath = await launcher.downloadInstaller(installerVersion);
|
|
@@ -86,7 +85,7 @@ program.command("install").description("Install plugins and themes into an Obsid
|
|
|
86
85
|
});
|
|
87
86
|
program.command("launch").summary("Download and launch Obsidian").description(
|
|
88
87
|
"Download and launch Obsidian, opening the specified vault. The Obsidian instance will have a sandboxed configuration directory."
|
|
89
|
-
).argument("[vault]", "Vault to open").option(...cacheOptionArgs).option(...versionOptionArgs).option(...
|
|
88
|
+
).argument("[vault]", "Vault to open").option(...cacheOptionArgs).option(...versionOptionArgs).option(...installerOptionArgs).option(...pluginOptionArgs).option(...themeOptionArgs).option("--copy", "Copy the vault first").action(async (vault, opts) => {
|
|
90
89
|
const launcher = new ObsidianLauncher({ cacheDir: opts.cache });
|
|
91
90
|
const { proc, configDir, vault: vaultCopy } = await launcher.launch({
|
|
92
91
|
appVersion: opts.version,
|
|
@@ -105,15 +104,16 @@ program.command("launch").summary("Download and launch Obsidian").description(
|
|
|
105
104
|
});
|
|
106
105
|
program.command("watch").summary("Launch Obsidian and watch for changes to plugins and themes").description(
|
|
107
106
|
'Downloads Obsidian and opens a vault, then watches for changes to plugins and themes.\n\nTakes the same arguments as the "launch" command but watches for changes to any local plugins or themes and updates the copies in the vault. Automatically installs the "pjeby/hot-reload" so plugins will hot reload as they are updated.'
|
|
108
|
-
).argument("[vault]", "Vault to open").option(...cacheOptionArgs).option(...versionOptionArgs).option(...
|
|
107
|
+
).argument("[vault]", "Vault to open").option(...cacheOptionArgs).option(...versionOptionArgs).option(...installerOptionArgs).option(...pluginOptionArgs).option(...themeOptionArgs).option("--copy", "Copy the vault first").action(async (vault, opts) => {
|
|
109
108
|
const launcher = new ObsidianLauncher({ cacheDir: opts.cache });
|
|
110
109
|
const plugins = await launcher.downloadPlugins(parsePlugins(opts.plugin));
|
|
111
110
|
const themes = await launcher.downloadThemes(parseThemes(opts.theme));
|
|
111
|
+
const copy = opts.copy ?? false;
|
|
112
112
|
const launchArgs = {
|
|
113
113
|
appVersion: opts.version,
|
|
114
114
|
installerVersion: opts.installerVersion,
|
|
115
115
|
vault,
|
|
116
|
-
copy
|
|
116
|
+
copy,
|
|
117
117
|
plugins,
|
|
118
118
|
themes
|
|
119
119
|
};
|
|
@@ -125,6 +125,9 @@ program.command("watch").summary("Launch Obsidian and watch for changes to plugi
|
|
|
125
125
|
stdio: "pipe"
|
|
126
126
|
}
|
|
127
127
|
});
|
|
128
|
+
if (copy) {
|
|
129
|
+
console.log(`Vault copied to ${vaultCopy}`);
|
|
130
|
+
}
|
|
128
131
|
proc.stdout.on("data", (data) => console.log(data.toString()));
|
|
129
132
|
proc.stderr.on("data", (data) => console.log(data.toString()));
|
|
130
133
|
const procExit = new Promise((resolve) => proc.on("exit", (code) => resolve(code ?? -1)));
|
|
@@ -164,7 +167,6 @@ program.command("watch").summary("Launch Obsidian and watch for changes to plugi
|
|
|
164
167
|
proc.kill("SIGTERM");
|
|
165
168
|
await procExit;
|
|
166
169
|
await fsAsync.rm(configDir, { recursive: true, force: true });
|
|
167
|
-
await fsAsync.rm(vaultCopy, { recursive: true, force: true });
|
|
168
170
|
process.exit(1);
|
|
169
171
|
};
|
|
170
172
|
process.on("SIGINT", cleanup);
|
|
@@ -190,5 +192,8 @@ program.command("create-versions-list").summary("Collect Obsidian version inform
|
|
|
190
192
|
fsAsync.writeFile(dest, JSON.stringify(versionInfos, void 0, 4));
|
|
191
193
|
console.log(`Wrote updated version information to ${dest}`);
|
|
192
194
|
});
|
|
193
|
-
program.
|
|
195
|
+
program.parseAsync().catch((err) => {
|
|
196
|
+
console.log(err?.message ?? err.toString());
|
|
197
|
+
process.exit(1);
|
|
198
|
+
});
|
|
194
199
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/bin/env node\nimport { Command } from 'commander';\nimport _ from \"lodash\";\nimport { ObsidianLauncher } from \"./launcher.js\"\nimport { PluginEntry, ThemeEntry } from \"./types.js\";\nimport fs from \"fs\";\nimport path from \"path\"\nimport fsAsync from \"fs/promises\";\n\n\nfunction parsePlugins(plugins: string[]): PluginEntry[] {\n return plugins.map((p: string) => {\n if (p.startsWith(\"id:\")) {\n return {id: p.slice(3)}\n } else if (p.startsWith(\"repo:\")) {\n return {repo: p.slice(5)}\n } else {\n return {path: p}\n }\n })\n}\n\nfunction parseThemes(themes: string[]): ThemeEntry[] {\n return themes.map((t: string, i: number) => {\n let result: ThemeEntry\n if (t.startsWith(\"name:\")) {\n result = {name: t.slice(5)}\n } else if (t.startsWith(\"repo:\")) {\n result = {repo: t.slice(5)}\n } else {\n result = {path: t}\n }\n return {...result, enabled: i == themes.length - 1}\n })\n}\n\n/**\n * Watch a list of files, calls func whenever there's an update. Debounced files changes.\n */\nfunction watchFiles(\n files: string[],\n func: (curr: fs.Stats, prev: fs.Stats) => void,\n options: { interval: number, persistent: boolean, debounce: number },\n) {\n const debouncedFunc = _.debounce((curr: fs.Stats, prev: fs.Stats) => {\n if (curr.mtimeMs > prev.mtimeMs || (curr.mtimeMs == 0 && prev.mtimeMs != 0)) {\n func(curr, prev)\n }\n }, options.debounce);\n for (const file of files) {\n fs.watchFile(file, {interval: options.interval, persistent: options.persistent}, debouncedFunc);\n }\n}\n\nconst versionOptionArgs = [\n '-v, --version <version>',\n \"Obsidian version to run\",\n \"latest\",\n] as const\nconst installerVersionOptionArgs = [\n '--installer-version <version>',\n \"Obsidian installer version to run\",\n \"latest\",\n] as const\nconst cacheOptionArgs = [\n '-c, --cache <cache>',\n 'Directory to use as the download cache',\n] as const\nconst pluginOptionArgs = [\n '-p, --plugin <plugin>',\n `Plugin to install. Format: \"<path>\" or \"repo:<github-repo>\" or \"id:<community-id>\". Can be repeated.`,\n (curr: string, prev: string[]) => [...prev, curr], [] as string[],\n] as const\nconst themeOptionArgs = [\n '-t, --theme <plugin>',\n `Theme to install. Format: \"<path>\" or \"repo:<github-repo>\" or \"name:<community-name>\". Can be repeated but only last will be enabled.`,\n (curr: string, prev: string[]) => [...prev, curr], [] as string[],\n] as const\n\nconst program = new Command(\"obsidian-launcher\");\n\nprogram\n .command(\"download\")\n .description(\"Download Obsidian to the cache\")\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerVersionOptionArgs)\n .action(async (opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n const [appVersion, installerVersion] = await launcher.resolveVersions(opts.version, opts.installerVersion);\n const installerPath = await launcher.downloadInstaller(installerVersion);\n console.log(`Downloaded Obsidian installer to ${installerPath}`)\n const appPath = await launcher.downloadApp(appVersion);\n console.log(`Downloaded Obsidian app to ${appPath}`)\n })\n\nprogram\n .command(\"install\")\n .description(\"Install plugins and themes into an Obsidian vault\")\n .argument('<vault>', 'Vault to install into')\n .option(...cacheOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .action(async (vault, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n await launcher.installPlugins(vault, parsePlugins(opts.plugin));\n await launcher.installThemes(vault, parseThemes(opts.theme));\n console.log(`Installed plugins and themes into ${vault}`)\n })\n\n\nprogram\n .command(\"launch\")\n .summary(\"Download and launch Obsidian\")\n .description(\n \"Download and launch Obsidian, opening the specified vault. The Obsidian instance will have a sandboxed \" +\n \"configuration directory.\"\n )\n .argument('[vault]', 'Vault to open')\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerVersionOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .option('--copy', \"Copy the vault first\")\n .action(async (vault: string|undefined, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n const {proc, configDir, vault: vaultCopy} = await launcher.launch({\n appVersion: opts.version, installerVersion: opts.installerVersion,\n vault: vault,\n copy: opts.copy ?? false,\n plugins: parsePlugins(opts.plugin),\n themes: parseThemes(opts.theme),\n spawnOptions: {\n detached: true,\n stdio: 'ignore',\n }\n })\n proc.unref() // Allow node to exit and leave proc running\n console.log(`Launched obsidian ${opts.version}`)\n })\n\nprogram\n .command(\"watch\")\n .summary(\"Launch Obsidian and watch for changes to plugins and themes\")\n .description(\n \"Downloads Obsidian and opens a vault, then watches for changes to plugins and themes.\\n\" +\n \"\\n\" +\n 'Takes the same arguments as the \"launch\" command but watches for changes to any local plugins or themes and ' +\n 'updates the copies in the vault. Automatically installs the \"pjeby/hot-reload\" so plugins will hot reload ' +\n 'as they are updated.'\n )\n .argument('[vault]', 'Vault to open')\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerVersionOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .option('--copy', \"Copy the vault first\")\n .action(async (vault: string, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n // Normalize the plugins and themes\n const plugins = await launcher.downloadPlugins(parsePlugins(opts.plugin));\n const themes = await launcher.downloadThemes(parseThemes(opts.theme));\n const launchArgs = {\n appVersion: opts.version, installerVersion: opts.installerVersion,\n vault: vault,\n copy: opts.copy ?? false,\n plugins: plugins,\n themes: themes,\n } as const\n\n const {proc, configDir, vault: vaultCopy} = await launcher.launch({\n ...launchArgs,\n plugins: [...plugins, {repo: \"pjeby/hot-reload\"}],\n spawnOptions: {\n detached: false,\n stdio: \"pipe\",\n }\n })\n proc.stdout!.on('data', data => console.log(data.toString()));\n proc.stderr!.on('data', data => console.log(data.toString()));\n const procExit = new Promise<number>((resolve) => proc.on('exit', (code) => resolve(code ?? -1)));\n\n for (const plugin of plugins) {\n if (plugin.originalType == \"local\") {\n watchFiles(\n [\"manifest.json\", \"main.js\", \"styles.css\", \"data.json\"].map(f => path.join(plugin.path, f)),\n async () => {\n console.log(`Detected change to \"${plugin.id}\"`);\n try {\n await launcher.installPlugins(vaultCopy!, [plugin]);\n } catch (e) {\n console.error(`Failed to update plugin \"${plugin.id}\": ${e}`)\n }\n },\n {interval: 500, persistent: false, debounce: 1000},\n )\n }\n }\n for (const theme of themes) {\n if (theme.originalType == \"local\") {\n watchFiles(\n [\"manifest.json\", \"theme.css\"].map(f => path.join(theme.path, f)),\n async () => {\n console.log(`Detected change to \"${theme.name}\"`);\n try {\n await launcher.installThemes(vaultCopy!, [theme]);\n } catch (e) {\n console.error(`Failed to update theme \"${theme.name}\": ${e}`)\n }\n },\n {interval: 500, persistent: false, debounce: 1000},\n )\n }\n }\n\n const cleanup = async () => {\n proc.kill(\"SIGTERM\");\n await procExit;\n await fsAsync.rm(configDir, {recursive: true, force: true});\n await fsAsync.rm(vaultCopy!, {recursive: true, force: true});\n process.exit(1);\n }\n process.on('SIGINT', cleanup);\n process.on('exit', cleanup);\n\n console.log(\"Watching for changes to plugins and themes...\")\n await procExit;\n })\n\nprogram\n .command(\"create-versions-list\")\n .summary(\"Collect Obsidian version information into a single file\")\n .description(\n \"Collect Obsidian version information into a single file.\\n\" +\n \"\\n\" +\n \"This command is used to collect Obsidian version information in one place including download links, the \" +\n \"minimum installer version, and the internal Electron version for every Obsidian release and beta version. \" +\n \"This info is available and automatically kept up to date at \" +\n \"https://raw.githubusercontent.com/jesse-r-s-hines/wdio-obsidian-service/HEAD/obsidian-versions.json \" +\n \"but you can use this command to recreate the file manually if you want.\"\n )\n .argument('dest', 'Path to output. If it already exists, it will update the information instead of creating it from scratch.')\n .option(...cacheOptionArgs)\n .option('--max-instances <count>', \"Number of parallel Obsidian instances to launch when checking Electron versions\", \"1\")\n .action(async (dest, opts) => {\n let versionInfos: any;\n try {\n versionInfos = JSON.parse(await fsAsync.readFile(dest, \"utf-8\"))\n } catch {\n versionInfos = undefined;\n }\n const maxInstances = Number(opts.maxInstances)\n if (isNaN(maxInstances)) {\n throw Error(`Invalid number ${opts.maxInstances}`)\n }\n\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n versionInfos = await launcher.updateObsidianVersionInfos(versionInfos, { maxInstances });\n fsAsync.writeFile(dest, JSON.stringify(versionInfos, undefined, 4));\n console.log(`Wrote updated version information to ${dest}`)\n })\n\nprogram.parse();\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/bin/env node\nimport { Command } from 'commander';\nimport _ from \"lodash\";\nimport { ObsidianLauncher } from \"./launcher.js\"\nimport { PluginEntry, ThemeEntry } from \"./types.js\";\nimport fs from \"fs\";\nimport path from \"path\"\nimport fsAsync from \"fs/promises\";\n\n\nfunction parsePlugins(plugins: string[] = []): PluginEntry[] {\n return plugins.map((p: string) => {\n if (p.startsWith(\"id:\")) {\n return {id: p.slice(3)}\n } else if (p.startsWith(\"repo:\")) {\n return {repo: p.slice(5)}\n } else {\n return {path: p}\n }\n })\n}\n\nfunction parseThemes(themes: string[] = []): ThemeEntry[] {\n return themes.map((t: string, i: number) => {\n let result: ThemeEntry\n if (t.startsWith(\"name:\")) {\n result = {name: t.slice(5)}\n } else if (t.startsWith(\"repo:\")) {\n result = {repo: t.slice(5)}\n } else {\n result = {path: t}\n }\n return {...result, enabled: i == themes.length - 1}\n })\n}\n\n/**\n * Watch a list of files, calls func whenever there's an update. Debounced files changes.\n */\nfunction watchFiles(\n files: string[],\n func: (curr: fs.Stats, prev: fs.Stats) => void,\n options: { interval: number, persistent: boolean, debounce: number },\n) {\n const debouncedFunc = _.debounce((curr: fs.Stats, prev: fs.Stats) => {\n if (curr.mtimeMs > prev.mtimeMs || (curr.mtimeMs == 0 && prev.mtimeMs != 0)) {\n func(curr, prev)\n }\n }, options.debounce);\n for (const file of files) {\n fs.watchFile(file, {interval: options.interval, persistent: options.persistent}, debouncedFunc);\n }\n}\n\nconst collectOpt = (curr: string, prev?: string[]) => [...(prev ?? []), curr];\n\nconst versionOptionArgs = [\n '-v, --version <version>',\n \"Obsidian version to run\",\n \"latest\",\n] as const\nconst installerOptionArgs = [\n '-i, --installer <version>',\n \"Obsidian installer version to run\",\n \"latest\",\n] as const\nconst cacheOptionArgs = [\n '-c, --cache <cache>',\n 'Directory to use as the download cache',\n] as const\nconst pluginOptionArgs = [\n '-p, --plugin <plugin>',\n `Plugin to install. Format: \"<path>\" or \"repo:<github-repo>\" or \"id:<community-id>\". Can be repeated.`,\n collectOpt,\n] as const\nconst themeOptionArgs = [\n '-t, --theme <plugin>',\n `Theme to install. Format: \"<path>\" or \"repo:<github-repo>\" or \"name:<community-name>\". Can be repeated but only last will be enabled.`,\n collectOpt,\n] as const\n\nconst program = new Command(\"obsidian-launcher\");\n\nprogram\n .command(\"download\")\n .description(\"Download Obsidian to the cache\")\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerOptionArgs)\n .action(async (opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n const [appVersion, installerVersion] = await launcher.resolveVersions(opts.version, opts.installerVersion);\n const installerPath = await launcher.downloadInstaller(installerVersion);\n console.log(`Downloaded Obsidian installer to ${installerPath}`)\n const appPath = await launcher.downloadApp(appVersion);\n console.log(`Downloaded Obsidian app to ${appPath}`)\n })\n\nprogram\n .command(\"install\")\n .description(\"Install plugins and themes into an Obsidian vault\")\n .argument('<vault>', 'Vault to install into')\n .option(...cacheOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .action(async (vault, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n await launcher.installPlugins(vault, parsePlugins(opts.plugin));\n await launcher.installThemes(vault, parseThemes(opts.theme));\n console.log(`Installed plugins and themes into ${vault}`)\n })\n\n\nprogram\n .command(\"launch\")\n .summary(\"Download and launch Obsidian\")\n .description(\n \"Download and launch Obsidian, opening the specified vault. The Obsidian instance will have a sandboxed \" +\n \"configuration directory.\"\n )\n .argument('[vault]', 'Vault to open')\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .option('--copy', \"Copy the vault first\")\n .action(async (vault: string|undefined, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n const {proc, configDir, vault: vaultCopy} = await launcher.launch({\n appVersion: opts.version, installerVersion: opts.installerVersion,\n vault: vault,\n copy: opts.copy ?? false,\n plugins: parsePlugins(opts.plugin),\n themes: parseThemes(opts.theme),\n spawnOptions: {\n detached: true,\n stdio: 'ignore',\n }\n })\n proc.unref() // Allow node to exit and leave proc running\n console.log(`Launched obsidian ${opts.version}`)\n })\n\nprogram\n .command(\"watch\")\n .summary(\"Launch Obsidian and watch for changes to plugins and themes\")\n .description(\n \"Downloads Obsidian and opens a vault, then watches for changes to plugins and themes.\\n\" +\n \"\\n\" +\n 'Takes the same arguments as the \"launch\" command but watches for changes to any local plugins or themes and ' +\n 'updates the copies in the vault. Automatically installs the \"pjeby/hot-reload\" so plugins will hot reload ' +\n 'as they are updated.'\n )\n .argument('[vault]', 'Vault to open')\n .option(...cacheOptionArgs)\n .option(...versionOptionArgs)\n .option(...installerOptionArgs)\n .option(...pluginOptionArgs)\n .option(...themeOptionArgs)\n .option('--copy', \"Copy the vault first\")\n .action(async (vault: string, opts) => {\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n // Normalize the plugins and themes\n const plugins = await launcher.downloadPlugins(parsePlugins(opts.plugin));\n const themes = await launcher.downloadThemes(parseThemes(opts.theme));\n const copy: boolean = opts.copy ?? false;\n const launchArgs = {\n appVersion: opts.version, installerVersion: opts.installerVersion,\n vault: vault,\n copy: copy,\n plugins: plugins,\n themes: themes,\n } as const\n\n const {proc, configDir, vault: vaultCopy} = await launcher.launch({\n ...launchArgs,\n plugins: [...plugins, {repo: \"pjeby/hot-reload\"}],\n spawnOptions: {\n detached: false,\n stdio: \"pipe\",\n }\n })\n if (copy) {\n console.log(`Vault copied to ${vaultCopy}`);\n }\n proc.stdout!.on('data', data => console.log(data.toString()));\n proc.stderr!.on('data', data => console.log(data.toString()));\n const procExit = new Promise<number>((resolve) => proc.on('exit', (code) => resolve(code ?? -1)));\n\n for (const plugin of plugins) {\n if (plugin.originalType == \"local\") {\n watchFiles(\n [\"manifest.json\", \"main.js\", \"styles.css\", \"data.json\"].map(f => path.join(plugin.path, f)),\n async () => {\n console.log(`Detected change to \"${plugin.id}\"`);\n try {\n await launcher.installPlugins(vaultCopy!, [plugin]);\n } catch (e) {\n console.error(`Failed to update plugin \"${plugin.id}\": ${e}`)\n }\n },\n {interval: 500, persistent: false, debounce: 1000},\n )\n }\n }\n for (const theme of themes) {\n if (theme.originalType == \"local\") {\n watchFiles(\n [\"manifest.json\", \"theme.css\"].map(f => path.join(theme.path, f)),\n async () => {\n console.log(`Detected change to \"${theme.name}\"`);\n try {\n await launcher.installThemes(vaultCopy!, [theme]);\n } catch (e) {\n console.error(`Failed to update theme \"${theme.name}\": ${e}`)\n }\n },\n {interval: 500, persistent: false, debounce: 1000},\n )\n }\n }\n\n const cleanup = async () => {\n proc.kill(\"SIGTERM\");\n await procExit;\n await fsAsync.rm(configDir, {recursive: true, force: true});\n process.exit(1);\n }\n process.on('SIGINT', cleanup);\n process.on('exit', cleanup);\n\n console.log(\"Watching for changes to plugins and themes...\")\n await procExit;\n })\n\nprogram\n .command(\"create-versions-list\")\n .summary(\"Collect Obsidian version information into a single file\")\n .description(\n \"Collect Obsidian version information into a single file.\\n\" +\n \"\\n\" +\n \"This command is used to collect Obsidian version information in one place including download links, the \" +\n \"minimum installer version, and the internal Electron version for every Obsidian release and beta version. \" +\n \"This info is available and automatically kept up to date at \" +\n \"https://raw.githubusercontent.com/jesse-r-s-hines/wdio-obsidian-service/HEAD/obsidian-versions.json \" +\n \"but you can use this command to recreate the file manually if you want.\"\n )\n .argument('dest', 'Path to output. If it already exists, it will update the information instead of creating it from scratch.')\n .option(...cacheOptionArgs)\n .option('--max-instances <count>', \"Number of parallel Obsidian instances to launch when checking Electron versions\", \"1\")\n .action(async (dest, opts) => {\n let versionInfos: any;\n try {\n versionInfos = JSON.parse(await fsAsync.readFile(dest, \"utf-8\"))\n } catch {\n versionInfos = undefined;\n }\n const maxInstances = Number(opts.maxInstances)\n if (isNaN(maxInstances)) {\n throw Error(`Invalid number ${opts.maxInstances}`)\n }\n\n const launcher = new ObsidianLauncher({cacheDir: opts.cache});\n versionInfos = await launcher.updateObsidianVersionInfos(versionInfos, { maxInstances });\n fsAsync.writeFile(dest, JSON.stringify(versionInfos, undefined, 4));\n console.log(`Wrote updated version information to ${dest}`)\n })\n\nprogram\n .parseAsync()\n .catch((err) => {\n console.log(err?.message ?? err.toString())\n process.exit(1);\n });\n"],"mappings":"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","names":[]}
|