obsidian-plugin-config 1.5.12 → 1.6.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/.vscode/tasks.json +5 -69
- package/DONE.md +60 -0
- package/FINAL_SUMMARY.md +163 -0
- package/README.md +70 -35
- package/bin/obsidian-inject.js +1 -1
- package/docs/APPLIED_MODIFS.md +104 -0
- package/docs/INTERACTIVE_INJECTION.md +137 -0
- package/docs/LLM-GUIDE.md +60 -50
- package/docs/TECHNICAL_NOTES.md +43 -0
- package/docs/implementation_plan.md +127 -0
- package/docs/modifs.md +434 -0
- package/package.json +3 -29
- package/scripts/acp.ts +7 -11
- package/scripts/build-npm.ts +78 -75
- package/scripts/help.ts +45 -107
- package/scripts/inject-core.ts +74 -36
- package/scripts/inject-options.ts +139 -0
- package/scripts/inject-path.ts +18 -4
- package/scripts/inject-prompt.ts +2 -1
- package/scripts/update-version-config.ts +2 -5
- package/templates/.gitattributes +4 -0
- package/templates/.github/workflows/release.yml +1 -1
- package/templates/.prettierignore +6 -0
- package/templates/.vscode/extensions.json +8 -0
- package/templates/.vscode/settings.json +0 -1
- package/templates/package.json +3 -2
- package/templates/scripts/esbuild.config.ts +16 -21
- package/tsconfig.json +2 -8
- package/.injection-info.json +0 -5
- package/docs/EXPORTS-EXPLAINED.md +0 -164
- package/manifest.json +0 -11
- package/scripts/esbuild.config.ts +0 -268
- package/scripts/sync-template-deps.ts +0 -59
- package/scripts/update-exports.js +0 -82
- package/src/index.ts +0 -6
- package/src/main.ts +0 -117
- package/src/modals/GenericConfirmModal.ts +0 -79
- package/src/modals/index.ts +0 -7
- package/src/tools/index.ts +0 -9
- package/src/utils/NoticeHelper.ts +0 -85
- package/src/utils/SettingsHelper.ts +0 -170
- package/src/utils/index.ts +0 -3
- package/versions.json +0 -64
|
@@ -1,268 +0,0 @@
|
|
|
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';
|
|
15
|
-
|
|
16
|
-
// Determine the plugin directory (where the script is called from)
|
|
17
|
-
const pluginDir = process.cwd();
|
|
18
|
-
|
|
19
|
-
// Create readline interface for prompts
|
|
20
|
-
const rl = createReadlineInterface();
|
|
21
|
-
|
|
22
|
-
async function promptForVaultPath(envKey: string): Promise<string> {
|
|
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;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async function updateEnvFile(envKey: string, vaultPath: string): Promise<void> {
|
|
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`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function validateVaultPath(vaultPath: string): boolean {
|
|
71
|
-
// Check if the path contains .obsidian directory
|
|
72
|
-
const obsidianPath = path.join(vaultPath, '.obsidian');
|
|
73
|
-
const pluginsPath = path.join(vaultPath, '.obsidian', 'plugins');
|
|
74
|
-
|
|
75
|
-
return fs.existsSync(obsidianPath) && fs.existsSync(pluginsPath);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function getVaultPath(vaultPath: string): string {
|
|
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
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const manifestPath = path.join(pluginDir, 'manifest.json');
|
|
96
|
-
|
|
97
|
-
// Check if manifest exists (for plugin-config itself, it might not exist)
|
|
98
|
-
if (!fs.existsSync(manifestPath)) {
|
|
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);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
|
|
107
|
-
|
|
108
|
-
config();
|
|
109
|
-
|
|
110
|
-
const EXTERNAL_DEPS = [
|
|
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
|
|
125
|
-
];
|
|
126
|
-
|
|
127
|
-
const BANNER = `/*
|
|
128
|
-
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
129
|
-
if you want to view the source, please visit the github repository of this plugin
|
|
130
|
-
*/`;
|
|
131
|
-
|
|
132
|
-
async function validateEnvironment(): Promise<void> {
|
|
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
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async function getBuildPath(isProd: boolean): Promise<string> {
|
|
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);
|
|
180
|
-
}
|
|
181
|
-
|
|
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
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
async function main(): Promise<void> {
|
|
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
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
main().catch(console.error);
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
|
|
6
|
-
const TEMPLATES_PKG = 'templates/package.json';
|
|
7
|
-
const TEMPLATES_SASS = 'templates/package-sass.json';
|
|
8
|
-
|
|
9
|
-
function resolvedVersion(dep: string): string | null {
|
|
10
|
-
const pkgPath = path.join('node_modules', dep, 'package.json');
|
|
11
|
-
if (!fs.existsSync(pkgPath)) return null;
|
|
12
|
-
try {
|
|
13
|
-
return JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version as string;
|
|
14
|
-
} catch {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function updateDeps(deps: Record<string, string>): { updated: string[] } {
|
|
20
|
-
const updated: string[] = [];
|
|
21
|
-
|
|
22
|
-
for (const dep of Object.keys(deps)) {
|
|
23
|
-
const current = deps[dep];
|
|
24
|
-
// Skip wildcards like "*"
|
|
25
|
-
if (current === '*') continue;
|
|
26
|
-
|
|
27
|
-
const resolved = resolvedVersion(dep);
|
|
28
|
-
if (!resolved) continue;
|
|
29
|
-
|
|
30
|
-
// Keep "latest" as-is, update pinned/range versions
|
|
31
|
-
if (current !== 'latest') {
|
|
32
|
-
const newVersion = `^${resolved}`;
|
|
33
|
-
if (deps[dep] !== newVersion) {
|
|
34
|
-
deps[dep] = newVersion;
|
|
35
|
-
updated.push(`${dep}: ${current} → ${newVersion}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return { updated };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function syncFile(filePath: string): void {
|
|
44
|
-
const pkg = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
45
|
-
const { updated } = updateDeps(pkg.devDependencies ?? {});
|
|
46
|
-
|
|
47
|
-
if (updated.length) {
|
|
48
|
-
fs.writeFileSync(filePath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
49
|
-
console.log(`\n✅ ${filePath}`);
|
|
50
|
-
for (const u of updated) console.log(` ${u}`);
|
|
51
|
-
} else {
|
|
52
|
-
console.log(`\n✅ ${filePath} — already up to date`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
console.log('🔄 Syncing template deps from node_modules...');
|
|
57
|
-
syncFile(TEMPLATES_PKG);
|
|
58
|
-
syncFile(TEMPLATES_SASS);
|
|
59
|
-
console.log('\n✅ Done.');
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
|
|
5
|
-
// Get current directory (equivalent to __dirname in CommonJS)
|
|
6
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = path.dirname(__filename);
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Scans the src directory for subdirectories with index.ts files
|
|
11
|
-
* and generates the main index.ts with appropriate exports
|
|
12
|
-
*/
|
|
13
|
-
function updateExports() {
|
|
14
|
-
console.log('🔄 Updating exports...');
|
|
15
|
-
|
|
16
|
-
const srcDir = path.join(__dirname, '../src');
|
|
17
|
-
const mainIndexPath = path.join(srcDir, 'index.ts');
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
// Check if src directory exists
|
|
21
|
-
if (!fs.existsSync(srcDir)) {
|
|
22
|
-
console.error('❌ src directory not found');
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Get all subdirectories in src/
|
|
27
|
-
const items = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
28
|
-
const subdirs = items
|
|
29
|
-
.filter(item => item.isDirectory())
|
|
30
|
-
.map(item => item.name);
|
|
31
|
-
|
|
32
|
-
// Find subdirectories that have an index.ts file
|
|
33
|
-
const exportsToGenerate = [];
|
|
34
|
-
|
|
35
|
-
for (const subdir of subdirs) {
|
|
36
|
-
const subdirPath = path.join(srcDir, subdir);
|
|
37
|
-
const indexPath = path.join(subdirPath, 'index.ts');
|
|
38
|
-
|
|
39
|
-
if (fs.existsSync(indexPath)) {
|
|
40
|
-
exportsToGenerate.push(subdir);
|
|
41
|
-
console.log(`✅ Found exportable module: ${subdir}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Generate the export statements
|
|
46
|
-
const exportStatements = exportsToGenerate
|
|
47
|
-
.map(subdir => `export * from './${subdir}/index.js';`)
|
|
48
|
-
.join('\n');
|
|
49
|
-
|
|
50
|
-
// Add header comment
|
|
51
|
-
const fileContent = `// Auto-generated exports - DO NOT EDIT MANUALLY
|
|
52
|
-
// Run 'npm run update-exports' to regenerate this file
|
|
53
|
-
|
|
54
|
-
${exportStatements}
|
|
55
|
-
`;
|
|
56
|
-
|
|
57
|
-
// Write the main index.ts file
|
|
58
|
-
fs.writeFileSync(mainIndexPath, fileContent, 'utf8');
|
|
59
|
-
|
|
60
|
-
// Update package.json exports
|
|
61
|
-
const packageJsonPath = path.join(__dirname, '../package.json');
|
|
62
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
63
|
-
|
|
64
|
-
// Generate exports object
|
|
65
|
-
const exportsObj = { ".": "./src/index.ts" };
|
|
66
|
-
packageJson.exports = exportsObj;
|
|
67
|
-
|
|
68
|
-
// Write updated package.json
|
|
69
|
-
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
|
|
70
|
-
|
|
71
|
-
console.log(`✅ Updated ${mainIndexPath}`);
|
|
72
|
-
console.log(`✅ Updated ${packageJsonPath} exports`);
|
|
73
|
-
console.log(`📦 Generated ${exportsToGenerate.length} export(s): ${exportsToGenerate.join(', ')}`);
|
|
74
|
-
|
|
75
|
-
} catch (error) {
|
|
76
|
-
console.error('❌ Error updating exports:', error.message);
|
|
77
|
-
process.exit(1);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Run the function
|
|
82
|
-
updateExports();
|
package/src/index.ts
DELETED
package/src/main.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import type { App } from 'obsidian';
|
|
2
|
-
import { Plugin, PluginSettingTab, Setting, Notice } from 'obsidian';
|
|
3
|
-
import { showConfirmModal } from './modals/GenericConfirmModal.ts';
|
|
4
|
-
// import { showTestMessage, getRandomEmoji } from "obsidian-plugin-config/tools";
|
|
5
|
-
|
|
6
|
-
interface MyPluginSettings {
|
|
7
|
-
mySetting: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const DEFAULT_SETTINGS: MyPluginSettings = {
|
|
11
|
-
mySetting: 'default'
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export default class ObsidianPluginConfigPlugin extends Plugin {
|
|
15
|
-
settings: MyPluginSettings;
|
|
16
|
-
|
|
17
|
-
async onload(): Promise<void> {
|
|
18
|
-
console.debug('Loading obsidian-plugin-config plugin for testing NPM exports');
|
|
19
|
-
await this.loadSettings();
|
|
20
|
-
|
|
21
|
-
this.addCommand({
|
|
22
|
-
id: 'show-confirmation-modal',
|
|
23
|
-
name: 'Test Confirmation Modal (Local)',
|
|
24
|
-
callback: () => this.showConfirmationModal()
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
this.addCommand({
|
|
28
|
-
id: 'show-centralized-modal',
|
|
29
|
-
name: 'Test Confirmation Modal (Centralized)',
|
|
30
|
-
callback: () => this.showCentralizedModal()
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
this.addCommand({
|
|
34
|
-
id: 'test-tools',
|
|
35
|
-
name: 'Test Centralized Tools',
|
|
36
|
-
callback: () => {
|
|
37
|
-
// const message = showTestMessage();
|
|
38
|
-
// const emoji = getRandomEmoji();
|
|
39
|
-
new Notice(`🎯 Test centralized tools (commented for autonomous mode)`);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
this.addSettingTab(new PluginConfigSettingTab(this.app, this));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private showConfirmationModal(): void {
|
|
47
|
-
showConfirmModal(this.app, {
|
|
48
|
-
title: 'Confirmation requise',
|
|
49
|
-
message:
|
|
50
|
-
'Êtes-vous sûr de vouloir effectuer cette action ? Cette action ne peut pas être annulée.',
|
|
51
|
-
confirmText: 'Confirmer',
|
|
52
|
-
cancelText: 'Annuler',
|
|
53
|
-
onConfirm: () => {
|
|
54
|
-
new Notice('Action confirmée !');
|
|
55
|
-
},
|
|
56
|
-
onCancel: () => {
|
|
57
|
-
new Notice('Action annulée.');
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private showCentralizedModal(): void {
|
|
63
|
-
showConfirmModal(this.app, {
|
|
64
|
-
title: 'Centralized Modal Test',
|
|
65
|
-
message:
|
|
66
|
-
'This modal comes from the centralized configuration! Pretty cool, right?',
|
|
67
|
-
confirmText: 'Awesome!',
|
|
68
|
-
cancelText: 'Not bad',
|
|
69
|
-
onConfirm: () => {
|
|
70
|
-
new Notice('Centralized modal confirmed! 🎉');
|
|
71
|
-
},
|
|
72
|
-
onCancel: () => {
|
|
73
|
-
new Notice('Centralized modal cancelled 😢');
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async loadSettings(): Promise<void> {
|
|
79
|
-
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async saveSettings(): Promise<void> {
|
|
83
|
-
await this.saveData(this.settings);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
class PluginConfigSettingTab extends PluginSettingTab {
|
|
88
|
-
plugin: ObsidianPluginConfigPlugin;
|
|
89
|
-
|
|
90
|
-
constructor(app: App, plugin: ObsidianPluginConfigPlugin) {
|
|
91
|
-
super(app, plugin);
|
|
92
|
-
this.plugin = plugin;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
display(): void {
|
|
96
|
-
const { containerEl } = this;
|
|
97
|
-
containerEl.empty();
|
|
98
|
-
|
|
99
|
-
containerEl.createEl('h2', { text: 'Obsidian Plugin Config Settings' });
|
|
100
|
-
containerEl.createEl('p', {
|
|
101
|
-
text: 'This plugin is used for testing NPM exports and development of the obsidian-plugin-config system.'
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
new Setting(containerEl)
|
|
105
|
-
.setName('Test Setting')
|
|
106
|
-
.setDesc('A test setting for development purposes')
|
|
107
|
-
.addText((text) =>
|
|
108
|
-
text
|
|
109
|
-
.setPlaceholder('Enter test value')
|
|
110
|
-
.setValue(this.plugin.settings.mySetting)
|
|
111
|
-
.onChange(async (value) => {
|
|
112
|
-
this.plugin.settings.mySetting = value;
|
|
113
|
-
await this.plugin.saveSettings();
|
|
114
|
-
})
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { App } from 'obsidian';
|
|
2
|
-
import { Modal } from 'obsidian';
|
|
3
|
-
|
|
4
|
-
export interface ConfirmModalOptions {
|
|
5
|
-
title: string;
|
|
6
|
-
message: string;
|
|
7
|
-
confirmText?: string;
|
|
8
|
-
cancelText?: string;
|
|
9
|
-
onConfirm: () => void;
|
|
10
|
-
onCancel?: () => void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class GenericConfirmModal extends Modal {
|
|
14
|
-
private options: ConfirmModalOptions;
|
|
15
|
-
|
|
16
|
-
constructor(app: App, options: ConfirmModalOptions) {
|
|
17
|
-
super(app);
|
|
18
|
-
this.options = options;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
onOpen(): void {
|
|
22
|
-
const { contentEl } = this;
|
|
23
|
-
contentEl.empty();
|
|
24
|
-
|
|
25
|
-
const title =
|
|
26
|
-
this.options.title.charAt(0).toUpperCase() + this.options.title.slice(1);
|
|
27
|
-
contentEl.createEl('h2', { text: title });
|
|
28
|
-
|
|
29
|
-
// Message
|
|
30
|
-
contentEl.createEl('p', { text: this.options.message });
|
|
31
|
-
|
|
32
|
-
// Buttons container
|
|
33
|
-
const buttonContainer = contentEl.createDiv('modal-button-container');
|
|
34
|
-
|
|
35
|
-
// Cancel button
|
|
36
|
-
const cancelBtn = buttonContainer.createEl('button', {
|
|
37
|
-
text: this.options.cancelText || 'Cancel',
|
|
38
|
-
cls: 'mod-cta'
|
|
39
|
-
});
|
|
40
|
-
cancelBtn.addEventListener('click', () => {
|
|
41
|
-
this.options.onCancel?.();
|
|
42
|
-
this.close();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// Confirm button
|
|
46
|
-
const confirmBtn = buttonContainer.createEl('button', {
|
|
47
|
-
text: this.options.confirmText || 'Confirm',
|
|
48
|
-
cls: 'mod-cta mod-warning'
|
|
49
|
-
});
|
|
50
|
-
confirmBtn.addEventListener('click', () => {
|
|
51
|
-
this.options.onConfirm();
|
|
52
|
-
this.close();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// Focus on confirm button
|
|
56
|
-
confirmBtn.focus();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
onClose(): void {
|
|
60
|
-
const { contentEl } = this;
|
|
61
|
-
contentEl.empty();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Utility function for quick usage
|
|
66
|
-
export function showConfirmModal(app: App, options: ConfirmModalOptions): void {
|
|
67
|
-
new GenericConfirmModal(app, options).open();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export async function confirmation(app: App, message: string): Promise<boolean> {
|
|
71
|
-
return new Promise((resolve) => {
|
|
72
|
-
new GenericConfirmModal(app, {
|
|
73
|
-
title: 'Confirm',
|
|
74
|
-
message,
|
|
75
|
-
onConfirm: () => resolve(true),
|
|
76
|
-
onCancel: () => resolve(false)
|
|
77
|
-
}).open();
|
|
78
|
-
});
|
|
79
|
-
}
|
package/src/modals/index.ts
DELETED
package/src/tools/index.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// Simple tools for testing
|
|
2
|
-
export function showTestMessage(): string {
|
|
3
|
-
return '✅ CENTRALIZED TOOLS WORK! This comes from obsidian-plugin-config!';
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export function getRandomEmoji(): string {
|
|
7
|
-
const emojis = ['🚀', '🎉', '✨', '🔥', '💯', '⚡', '🎯', '🌟'];
|
|
8
|
-
return emojis[Math.floor(Math.random() * emojis.length)];
|
|
9
|
-
}
|