obsidian-plugin-config 1.4.4 → 1.4.6

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.
@@ -1,12 +1,17 @@
1
- import esbuild from "esbuild";
2
- import process from "process";
3
- import builtins from "builtin-modules";
4
- import { config } from "dotenv";
5
- import path from "path";
6
- import { readFileSync } from "fs";
7
- import { rm } from "fs/promises";
8
- import fs from "fs";
9
- import { isValidPath, copyFilesToTargetDir, askQuestion, createReadlineInterface } from "./utils.js";
1
+ import esbuild from 'esbuild';
2
+ import process from 'process';
3
+ import builtins from 'builtin-modules';
4
+ import { config } from 'dotenv';
5
+ import path from 'path';
6
+ import { readFileSync } from 'fs';
7
+ import { rm } from 'fs/promises';
8
+ import fs from 'fs';
9
+ import {
10
+ isValidPath,
11
+ copyFilesToTargetDir,
12
+ askQuestion,
13
+ createReadlineInterface
14
+ } from './utils.js';
10
15
 
11
16
  // Determine the plugin directory (where the script is called from)
12
17
  const pluginDir = process.cwd();
@@ -15,104 +20,108 @@ const pluginDir = process.cwd();
15
20
  const rl = createReadlineInterface();
16
21
 
17
22
  async function promptForVaultPath(envKey: string): Promise<string> {
18
- const vaultType = envKey === "REAL_VAULT" ? "real" : "test";
19
- const usage = envKey === "REAL_VAULT"
20
- ? "for final plugin installation"
21
- : "for development and testing";
22
-
23
- console.log(`❓ ${envKey} path is required ${usage}`);
24
- const path = await askQuestion(`📝 Enter your ${vaultType} vault path (or Ctrl+C to cancel): `, rl);
25
-
26
- if (!path) {
27
- console.log('❌ No path provided, exiting...');
28
- process.exit(1);
29
- }
30
-
31
- return path;
23
+ const vaultType = envKey === 'REAL_VAULT' ? 'real' : 'test';
24
+ const usage =
25
+ envKey === 'REAL_VAULT'
26
+ ? 'for final plugin installation'
27
+ : 'for development and testing';
28
+
29
+ console.log(`❓ ${envKey} path is required ${usage}`);
30
+ const path = await askQuestion(
31
+ `📝 Enter your ${vaultType} vault path (or Ctrl+C to cancel): `,
32
+ rl
33
+ );
34
+
35
+ if (!path) {
36
+ console.log('❌ No path provided, exiting...');
37
+ process.exit(1);
38
+ }
39
+
40
+ return path;
32
41
  }
33
42
 
34
-
35
-
36
43
  async function updateEnvFile(envKey: string, vaultPath: string): Promise<void> {
37
- const envPath = path.join(pluginDir, '.env');
38
- let envContent = '';
39
-
40
- // Read existing .env if it exists
41
- try {
42
- envContent = readFileSync(envPath, 'utf8');
43
- } catch {
44
- // File doesn't exist, start with empty content
45
- }
46
-
47
- // Update or add the variable
48
- const regex = new RegExp(`^${envKey}=.*$`, 'm');
49
- const newLine = `${envKey}=${vaultPath}`;
50
-
51
- if (regex.test(envContent)) {
52
- envContent = envContent.replace(regex, newLine);
53
- } else {
54
- envContent += envContent.endsWith('\n') ? '' : '\n';
55
- envContent += newLine + '\n';
56
- }
57
-
58
- // Write back to .env
59
- await import('fs').then(fs => fs.writeFileSync(envPath, envContent));
60
- console.log(`✅ Updated ${envKey} in .env file`);
44
+ const envPath = path.join(pluginDir, '.env');
45
+ let envContent = '';
46
+
47
+ // Read existing .env if it exists
48
+ try {
49
+ envContent = readFileSync(envPath, 'utf8');
50
+ } catch {
51
+ // File doesn't exist, start with empty content
52
+ }
53
+
54
+ // Update or add the variable
55
+ const regex = new RegExp(`^${envKey}=.*$`, 'm');
56
+ const newLine = `${envKey}=${vaultPath}`;
57
+
58
+ if (regex.test(envContent)) {
59
+ envContent = envContent.replace(regex, newLine);
60
+ } else {
61
+ envContent += envContent.endsWith('\n') ? '' : '\n';
62
+ envContent += newLine + '\n';
63
+ }
64
+
65
+ // Write back to .env
66
+ await import('fs').then((fs) => fs.writeFileSync(envPath, envContent));
67
+ console.log(`✅ Updated ${envKey} in .env file`);
61
68
  }
62
69
 
63
70
  function validateVaultPath(vaultPath: string): boolean {
64
- // Check if the path contains .obsidian directory
65
- const obsidianPath = path.join(vaultPath, ".obsidian");
66
- const pluginsPath = path.join(vaultPath, ".obsidian", "plugins");
71
+ // Check if the path contains .obsidian directory
72
+ const obsidianPath = path.join(vaultPath, '.obsidian');
73
+ const pluginsPath = path.join(vaultPath, '.obsidian', 'plugins');
67
74
 
68
- return fs.existsSync(obsidianPath) && fs.existsSync(pluginsPath);
75
+ return fs.existsSync(obsidianPath) && fs.existsSync(pluginsPath);
69
76
  }
70
77
 
71
78
  function getVaultPath(vaultPath: string): string {
72
- // Validate that this is a proper vault path
73
- if (!validateVaultPath(vaultPath)) {
74
- console.error(`❌ Invalid vault path: ${vaultPath}`);
75
- console.error(` The path must contain a .obsidian/plugins directory`);
76
- console.error(` Please enter a valid Obsidian vault path`);
77
- process.exit(1);
78
- }
79
-
80
- // Check if the path already contains the plugins directory path
81
- const pluginsPath = path.join(".obsidian", "plugins");
82
- if (vaultPath.includes(pluginsPath)) {
83
- return path.join(vaultPath, manifest.id);
84
- } else {
85
- return path.join(vaultPath, ".obsidian", "plugins", manifest.id);
86
- }
79
+ // Validate that this is a proper vault path
80
+ if (!validateVaultPath(vaultPath)) {
81
+ console.error(`❌ Invalid vault path: ${vaultPath}`);
82
+ console.error(` The path must contain a .obsidian/plugins directory`);
83
+ console.error(` Please enter a valid Obsidian vault path`);
84
+ process.exit(1);
85
+ }
86
+
87
+ // Check if the path already contains the plugins directory path
88
+ const pluginsPath = path.join('.obsidian', 'plugins');
89
+ if (vaultPath.includes(pluginsPath)) {
90
+ return path.join(vaultPath, manifest.id);
91
+ } else {
92
+ return path.join(vaultPath, '.obsidian', 'plugins', manifest.id);
93
+ }
87
94
  }
88
- const manifestPath = path.join(pluginDir, "manifest.json");
95
+ const manifestPath = path.join(pluginDir, 'manifest.json');
89
96
 
90
97
  // Check if manifest exists (for plugin-config itself, it might not exist)
91
98
  if (!fs.existsSync(manifestPath)) {
92
- console.log("⚠️ No manifest.json found - this script is designed for Obsidian plugins");
93
- console.log(" If you're building plugin-config itself, use 'tsc' instead");
94
- process.exit(0);
99
+ console.log(
100
+ '⚠️ No manifest.json found - this script is designed for Obsidian plugins'
101
+ );
102
+ console.log(" If you're building plugin-config itself, use 'tsc' instead");
103
+ process.exit(0);
95
104
  }
96
105
 
97
- const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
106
+ const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
98
107
 
99
108
  config();
100
109
 
101
110
  const EXTERNAL_DEPS = [
102
- "obsidian",
103
- "electron",
104
- "@codemirror/autocomplete",
105
- "@codemirror/collab",
106
- "@codemirror/commands",
107
- "@codemirror/language",
108
- "@codemirror/lint",
109
- "@codemirror/search",
110
- "@codemirror/state",
111
- "@codemirror/view",
112
- "@lezer/common",
113
- "@lezer/highlight",
114
- "@lezer/lr",
115
- ...builtins
111
+ 'obsidian',
112
+ 'electron',
113
+ '@codemirror/autocomplete',
114
+ '@codemirror/collab',
115
+ '@codemirror/commands',
116
+ '@codemirror/language',
117
+ '@codemirror/lint',
118
+ '@codemirror/search',
119
+ '@codemirror/state',
120
+ '@codemirror/view',
121
+ '@lezer/common',
122
+ '@lezer/highlight',
123
+ '@lezer/lr',
124
+ ...builtins
116
125
  ];
117
126
 
118
127
  const BANNER = `/*
@@ -121,123 +130,139 @@ if you want to view the source, please visit the github repository of this plugi
121
130
  */`;
122
131
 
123
132
  async function validateEnvironment(): Promise<void> {
124
- const srcMainPath = path.join(pluginDir, "src/main.ts");
125
- if (!await isValidPath(srcMainPath)) {
126
- throw new Error("Invalid path for src/main.ts. main.ts must be in the src directory");
127
- }
128
- if (!await isValidPath(manifestPath)) {
129
- throw new Error("Invalid path for manifest.json");
130
- }
133
+ const srcMainPath = path.join(pluginDir, 'src/main.ts');
134
+ if (!(await isValidPath(srcMainPath))) {
135
+ throw new Error(
136
+ 'Invalid path for src/main.ts. main.ts must be in the src directory'
137
+ );
138
+ }
139
+ if (!(await isValidPath(manifestPath))) {
140
+ throw new Error('Invalid path for manifest.json');
141
+ }
131
142
  }
132
143
 
133
144
  async function getBuildPath(isProd: boolean): Promise<string> {
134
- // Check if we should use real vault (either -r flag or "real" argument)
135
- const useRealVault = process.argv.includes("-r") || process.argv.includes("real");
136
-
137
- // If production build without redirection, return plugin directory
138
- if (isProd && !useRealVault) {
139
- return pluginDir;
140
- }
141
-
142
- // Determine which path to use
143
- const envKey = useRealVault ? "REAL_VAULT" : "TEST_VAULT";
144
- const vaultPath = process.env[envKey]?.trim();
145
-
146
- // If empty or undefined, we're already in the plugin folder
147
- if (!vaultPath) {
148
- // Check if we're in Obsidian plugins folder
149
- const currentPath = process.cwd();
150
- const isInObsidianPlugins = currentPath.includes('.obsidian/plugins') ||
151
- currentPath.includes('.obsidian\\plugins');
152
-
153
- if (isInObsidianPlugins) {
154
- // In obsidian/plugins: allow in-place development
155
- console.log(`ℹ️ Building in Obsidian plugins folder (in-place development)`);
156
- return pluginDir;
157
- } else {
158
- // External development: prompt for missing vault path
159
- const newPath = await promptForVaultPath(envKey);
160
- await updateEnvFile(envKey, newPath);
161
- config();
162
- return getVaultPath(newPath);
163
- }
164
- }
165
-
166
- // If we reach here, use the vault path directly
167
- return getVaultPath(vaultPath);
145
+ // Check if we should use real vault (either -r flag or "real" argument)
146
+ const useRealVault = process.argv.includes('-r') || process.argv.includes('real');
147
+
148
+ // If production build without redirection, return plugin directory
149
+ if (isProd && !useRealVault) {
150
+ return pluginDir;
151
+ }
152
+
153
+ // Determine which path to use
154
+ const envKey = useRealVault ? 'REAL_VAULT' : 'TEST_VAULT';
155
+ const vaultPath = process.env[envKey]?.trim();
156
+
157
+ // If empty or undefined, we're already in the plugin folder
158
+ if (!vaultPath) {
159
+ // Check if we're in Obsidian plugins folder
160
+ const currentPath = process.cwd();
161
+ const isInObsidianPlugins =
162
+ currentPath.includes('.obsidian/plugins') ||
163
+ currentPath.includes('.obsidian\\plugins');
164
+
165
+ if (isInObsidianPlugins) {
166
+ // In obsidian/plugins: allow in-place development
167
+ console.log(`ℹ️ Building in Obsidian plugins folder (in-place development)`);
168
+ return pluginDir;
169
+ } else {
170
+ // External development: prompt for missing vault path
171
+ const newPath = await promptForVaultPath(envKey);
172
+ await updateEnvFile(envKey, newPath);
173
+ config();
174
+ return getVaultPath(newPath);
175
+ }
176
+ }
177
+
178
+ // If we reach here, use the vault path directly
179
+ return getVaultPath(vaultPath);
168
180
  }
169
181
 
170
- async function createBuildContext(buildPath: string, isProd: boolean, entryPoints: string[]): Promise<esbuild.BuildContext> {
171
- return await esbuild.context({
172
- banner: { js: BANNER },
173
- minify: isProd,
174
- entryPoints,
175
- bundle: true,
176
- external: EXTERNAL_DEPS,
177
- format: "cjs",
178
- target: "esNext",
179
- platform: "node",
180
- logLevel: "info",
181
- sourcemap: isProd ? false : "inline",
182
- treeShaking: true,
183
- outdir: buildPath,
184
- outbase: path.join(pluginDir, "src"),
185
- plugins: [
186
- {
187
- name: "copy-to-plugins-folder",
188
- setup: (build): void => {
189
- build.onEnd(async () => {
190
- // if real or build
191
- if (isProd) {
192
- if (process.argv.includes("-r") || process.argv.includes("real")) {
193
- await copyFilesToTargetDir(buildPath);
194
- console.log(`Successfully installed in ${buildPath}`);
195
- } else {
196
- const folderToRemove = path.join(buildPath, "_.._");
197
- if (await isValidPath(folderToRemove)) {
198
- await rm(folderToRemove, { recursive: true });
199
- }
200
- console.log("Built done in initial folder");
201
- }
202
- }
203
- // if watch (dev)
204
- else {
205
- await copyFilesToTargetDir(buildPath);
206
- }
207
- });
208
- }
209
- }
210
- ]
211
- });
182
+ async function createBuildContext(
183
+ buildPath: string,
184
+ isProd: boolean,
185
+ entryPoints: string[]
186
+ ): Promise<esbuild.BuildContext> {
187
+ return await esbuild.context({
188
+ banner: { js: BANNER },
189
+ minify: isProd,
190
+ entryPoints,
191
+ bundle: true,
192
+ external: EXTERNAL_DEPS,
193
+ format: 'cjs',
194
+ target: 'esNext',
195
+ platform: 'node',
196
+ logLevel: 'info',
197
+ sourcemap: isProd ? false : 'inline',
198
+ treeShaking: true,
199
+ outdir: buildPath,
200
+ outbase: path.join(pluginDir, 'src'),
201
+ plugins: [
202
+ {
203
+ name: 'copy-to-plugins-folder',
204
+ setup: (build): void => {
205
+ build.onEnd(async () => {
206
+ // if real or build
207
+ if (isProd) {
208
+ if (
209
+ process.argv.includes('-r') ||
210
+ process.argv.includes('real')
211
+ ) {
212
+ await copyFilesToTargetDir(buildPath);
213
+ console.log(`Successfully installed in ${buildPath}`);
214
+ } else {
215
+ const folderToRemove = path.join(buildPath, '_.._');
216
+ if (await isValidPath(folderToRemove)) {
217
+ await rm(folderToRemove, { recursive: true });
218
+ }
219
+ console.log('Built done in initial folder');
220
+ }
221
+ }
222
+ // if watch (dev)
223
+ else {
224
+ await copyFilesToTargetDir(buildPath);
225
+ }
226
+ });
227
+ }
228
+ }
229
+ ]
230
+ });
212
231
  }
213
232
 
214
233
  async function main(): Promise<void> {
215
- try {
216
- await validateEnvironment();
217
- const isProd = process.argv[2] === "production";
218
- const buildPath = await getBuildPath(isProd);
219
- console.log(buildPath === pluginDir
220
- ? "Building in initial folder"
221
- : `Building in ${buildPath}`);
222
- const srcStylesPath = path.join(pluginDir, "src/styles.css");
223
- const rootStylesPath = path.join(pluginDir, "styles.css");
224
- const stylePath = await isValidPath(srcStylesPath) ? srcStylesPath : await isValidPath(rootStylesPath) ? rootStylesPath : "";
225
- const mainTsPath = path.join(pluginDir, "src/main.ts");
226
- const entryPoints = stylePath ? [mainTsPath, stylePath] : [mainTsPath];
227
- const context = await createBuildContext(buildPath, isProd, entryPoints);
228
-
229
- if (isProd) {
230
- await context.rebuild();
231
- rl.close();
232
- process.exit(0);
233
- } else {
234
- await context.watch();
235
- }
236
- } catch (error) {
237
- console.error("Build failed:", error);
238
- rl.close();
239
- process.exit(1);
240
- }
234
+ try {
235
+ await validateEnvironment();
236
+ const isProd = process.argv[2] === 'production';
237
+ const buildPath = await getBuildPath(isProd);
238
+ console.log(
239
+ buildPath === pluginDir
240
+ ? 'Building in initial folder'
241
+ : `Building in ${buildPath}`
242
+ );
243
+ const srcStylesPath = path.join(pluginDir, 'src/styles.css');
244
+ const rootStylesPath = path.join(pluginDir, 'styles.css');
245
+ const stylePath = (await isValidPath(srcStylesPath))
246
+ ? srcStylesPath
247
+ : (await isValidPath(rootStylesPath))
248
+ ? rootStylesPath
249
+ : '';
250
+ const mainTsPath = path.join(pluginDir, 'src/main.ts');
251
+ const entryPoints = stylePath ? [mainTsPath, stylePath] : [mainTsPath];
252
+ const context = await createBuildContext(buildPath, isProd, entryPoints);
253
+
254
+ if (isProd) {
255
+ await context.rebuild();
256
+ rl.close();
257
+ process.exit(0);
258
+ } else {
259
+ await context.watch();
260
+ }
261
+ } catch (error) {
262
+ console.error('Build failed:', error);
263
+ rl.close();
264
+ process.exit(1);
265
+ }
241
266
  }
242
267
 
243
268
  main().catch(console.error);