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.
- package/.injection-info.json +5 -1
- package/.vscode/tasks.json +116 -116
- package/bin/obsidian-inject.js +1 -1
- package/package.json +3 -1
- package/scripts/acp.ts +64 -56
- package/scripts/build-npm.ts +152 -135
- package/scripts/esbuild.config.ts +221 -196
- package/scripts/inject-core.ts +613 -619
- package/scripts/inject-path.ts +144 -130
- package/scripts/inject-prompt.ts +85 -78
- package/scripts/sync-template-deps.ts +44 -44
- package/scripts/update-version-config.ts +117 -98
- package/scripts/utils.ts +121 -118
- package/templates/.vscode/settings.json +9 -9
- package/templates/.vscode/tasks.json +53 -53
- package/templates/package.json +3 -1
- package/templates/scripts/acp.ts +64 -56
- package/templates/scripts/esbuild.config.ts +268 -232
- package/templates/scripts/release.ts +78 -79
- package/templates/scripts/update-version.ts +129 -106
- package/templates/scripts/utils.ts +129 -126
- package/tsconfig.json +30 -41
- package/versions.json +3 -1
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import esbuild from
|
|
2
|
-
import process from
|
|
3
|
-
import builtins from
|
|
4
|
-
import { config } from
|
|
5
|
-
import path from
|
|
6
|
-
import { readFileSync } from
|
|
7
|
-
import { rm } from
|
|
8
|
-
import fs from
|
|
9
|
-
import {
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
75
|
+
return fs.existsSync(obsidianPath) && fs.existsSync(pluginsPath);
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
function getVaultPath(vaultPath: string): string {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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,
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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,
|
|
106
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
|
|
98
107
|
|
|
99
108
|
config();
|
|
100
109
|
|
|
101
110
|
const EXTERNAL_DEPS = [
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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);
|