obsidian-plugin-config 1.0.2

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.
Files changed (55) hide show
  1. package/.vscode/settings.json +4 -0
  2. package/README.md +45 -0
  3. package/bin/obsidian-inject.js +98 -0
  4. package/obsidian-plugin-config-1.0.2.tgz +0 -0
  5. package/package.json +88 -0
  6. package/scripts/acp.ts +71 -0
  7. package/scripts/build-npm.ts +137 -0
  8. package/scripts/esbuild.config.ts +311 -0
  9. package/scripts/help.ts +46 -0
  10. package/scripts/inject-path.ts +487 -0
  11. package/scripts/inject-prompt.ts +399 -0
  12. package/scripts/open-editor.mjs +18 -0
  13. package/scripts/release.ts +97 -0
  14. package/scripts/update-exports.js +91 -0
  15. package/scripts/update-version-config.ts +98 -0
  16. package/scripts/update-version.ts +102 -0
  17. package/scripts/utils.ts +117 -0
  18. package/src/index.ts +6 -0
  19. package/src/main_test.ts +106 -0
  20. package/src/modals/GenericConfirmModal.ts +67 -0
  21. package/src/modals/index.ts +3 -0
  22. package/src/test-centralized-utils.ts +23 -0
  23. package/src/tools/index.ts +9 -0
  24. package/src/utils/NoticeHelper.ts +102 -0
  25. package/src/utils/SettingsHelper.ts +180 -0
  26. package/src/utils/index.ts +3 -0
  27. package/templates/.vscode/settings.json +4 -0
  28. package/templates/eslint.config.ts +48 -0
  29. package/templates/help-plugin.ts +39 -0
  30. package/templates/package-versions.json +28 -0
  31. package/templates/tsconfig.json +37 -0
  32. package/test-plugin/manifest.json +10 -0
  33. package/test-plugin/package.json +38 -0
  34. package/test-plugin/scripts/acp.ts +71 -0
  35. package/test-plugin/scripts/esbuild.config.ts +165 -0
  36. package/test-plugin/scripts/help.ts +29 -0
  37. package/test-plugin/scripts/release.ts +97 -0
  38. package/test-plugin/scripts/update-version.ts +102 -0
  39. package/test-plugin/scripts/utils.ts +117 -0
  40. package/test-plugin/src/main.ts +11 -0
  41. package/test-plugin/yarn.lock +386 -0
  42. package/test-plugin-v2/main.js +5 -0
  43. package/test-plugin-v2/manifest.json +10 -0
  44. package/test-plugin-v2/package.json +40 -0
  45. package/test-plugin-v2/scripts/acp.ts +71 -0
  46. package/test-plugin-v2/scripts/esbuild.config.ts +165 -0
  47. package/test-plugin-v2/scripts/help.ts +29 -0
  48. package/test-plugin-v2/scripts/release.ts +97 -0
  49. package/test-plugin-v2/scripts/update-version.ts +102 -0
  50. package/test-plugin-v2/scripts/utils.ts +117 -0
  51. package/test-plugin-v2/src/main.ts +11 -0
  52. package/test-plugin-v2/tsconfig.json +31 -0
  53. package/test-plugin-v2/yarn.lock +1986 -0
  54. package/tsconfig.json +38 -0
  55. package/versions.json +5 -0
@@ -0,0 +1,180 @@
1
+ import { Setting } from "obsidian";
2
+
3
+ /**
4
+ * Helper for creating common setting types with consistent styling
5
+ */
6
+ export class SettingsHelper {
7
+
8
+ /**
9
+ * Create a text input setting
10
+ */
11
+ static createTextSetting(
12
+ containerEl: HTMLElement,
13
+ name: string,
14
+ desc: string,
15
+ value: string,
16
+ onChange: (value: string) => void,
17
+ placeholder?: string
18
+ ): Setting {
19
+ return new Setting(containerEl)
20
+ .setName(name)
21
+ .setDesc(desc)
22
+ .addText(text => text
23
+ .setPlaceholder(placeholder || "")
24
+ .setValue(value)
25
+ .onChange(onChange)
26
+ );
27
+ }
28
+
29
+ /**
30
+ * Create a toggle setting
31
+ */
32
+ static createToggleSetting(
33
+ containerEl: HTMLElement,
34
+ name: string,
35
+ desc: string,
36
+ value: boolean,
37
+ onChange: (value: boolean) => void
38
+ ): Setting {
39
+ return new Setting(containerEl)
40
+ .setName(name)
41
+ .setDesc(desc)
42
+ .addToggle(toggle => toggle
43
+ .setValue(value)
44
+ .onChange(onChange)
45
+ );
46
+ }
47
+
48
+ /**
49
+ * Create a dropdown setting
50
+ */
51
+ static createDropdownSetting(
52
+ containerEl: HTMLElement,
53
+ name: string,
54
+ desc: string,
55
+ options: Record<string, string>,
56
+ value: string,
57
+ onChange: (value: string) => void
58
+ ): Setting {
59
+ return new Setting(containerEl)
60
+ .setName(name)
61
+ .setDesc(desc)
62
+ .addDropdown(dropdown => {
63
+ Object.entries(options).forEach(([key, label]) => {
64
+ dropdown.addOption(key, label);
65
+ });
66
+ dropdown
67
+ .setValue(value)
68
+ .onChange(onChange);
69
+ });
70
+ }
71
+
72
+ /**
73
+ * Create a number input setting
74
+ */
75
+ static createNumberSetting(
76
+ containerEl: HTMLElement,
77
+ name: string,
78
+ desc: string,
79
+ value: number,
80
+ onChange: (value: number) => void,
81
+ min?: number,
82
+ max?: number,
83
+ step?: number
84
+ ): Setting {
85
+ return new Setting(containerEl)
86
+ .setName(name)
87
+ .setDesc(desc)
88
+ .addText(text => {
89
+ text.inputEl.type = "number";
90
+ if (min !== undefined) text.inputEl.min = min.toString();
91
+ if (max !== undefined) text.inputEl.max = max.toString();
92
+ if (step !== undefined) text.inputEl.step = step.toString();
93
+
94
+ text
95
+ .setValue(value.toString())
96
+ .onChange(val => {
97
+ const num = parseFloat(val);
98
+ if (!isNaN(num)) onChange(num);
99
+ });
100
+ });
101
+ }
102
+
103
+ /**
104
+ * Create a button setting
105
+ */
106
+ static createButtonSetting(
107
+ containerEl: HTMLElement,
108
+ name: string,
109
+ desc: string,
110
+ buttonText: string,
111
+ onClick: () => void
112
+ ): Setting {
113
+ return new Setting(containerEl)
114
+ .setName(name)
115
+ .setDesc(desc)
116
+ .addButton(button => button
117
+ .setButtonText(buttonText)
118
+ .onClick(onClick)
119
+ );
120
+ }
121
+
122
+ /**
123
+ * Create a section header
124
+ */
125
+ static createHeader(
126
+ containerEl: HTMLElement,
127
+ title: string,
128
+ description?: string
129
+ ): void {
130
+ const headerEl = containerEl.createEl("h3", { text: title });
131
+ headerEl.style.marginTop = "20px";
132
+ headerEl.style.marginBottom = "10px";
133
+ headerEl.style.borderBottom = "1px solid var(--background-modifier-border)";
134
+ headerEl.style.paddingBottom = "5px";
135
+
136
+ if (description) {
137
+ const descEl = containerEl.createEl("p", { text: description });
138
+ descEl.style.marginTop = "0";
139
+ descEl.style.marginBottom = "15px";
140
+ descEl.style.color = "var(--text-muted)";
141
+ descEl.style.fontSize = "0.9em";
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Create a collapsible section
147
+ */
148
+ static createCollapsibleSection(
149
+ containerEl: HTMLElement,
150
+ title: string,
151
+ isOpen: boolean = false
152
+ ): { container: HTMLElement; toggle: () => void } {
153
+ const sectionEl = containerEl.createDiv("setting-item");
154
+ const headerEl = sectionEl.createDiv("setting-item-info");
155
+ const nameEl = headerEl.createDiv("setting-item-name");
156
+ nameEl.setText(title);
157
+ nameEl.style.cursor = "pointer";
158
+ nameEl.style.userSelect = "none";
159
+
160
+ const contentEl = containerEl.createDiv("collapsible-content");
161
+ contentEl.style.display = isOpen ? "block" : "none";
162
+ contentEl.style.marginLeft = "20px";
163
+ contentEl.style.marginTop = "10px";
164
+
165
+ const arrow = nameEl.createSpan("collapse-icon");
166
+ arrow.setText(isOpen ? "▼" : "▶");
167
+ arrow.style.marginRight = "8px";
168
+ arrow.style.fontSize = "0.8em";
169
+
170
+ const toggle = () => {
171
+ const isCurrentlyOpen = contentEl.style.display !== "none";
172
+ contentEl.style.display = isCurrentlyOpen ? "none" : "block";
173
+ arrow.setText(isCurrentlyOpen ? "▶" : "▼");
174
+ };
175
+
176
+ nameEl.addEventListener("click", toggle);
177
+
178
+ return { container: contentEl, toggle };
179
+ }
180
+ }
@@ -0,0 +1,3 @@
1
+ // Centralized utils exports for Obsidian plugins
2
+ export { NoticeHelper } from './NoticeHelper.js';
3
+ export { SettingsHelper } from './SettingsHelper.js';
@@ -0,0 +1,4 @@
1
+ {
2
+ "npm.packageManager": "yarn",
3
+ "typescript.preferences.includePackageJsonAutoImports": "off"
4
+ }
@@ -0,0 +1,48 @@
1
+ import * as typescriptEslintParser from "@typescript-eslint/parser";
2
+ import typescriptEslintPlugin from "@typescript-eslint/eslint-plugin";
3
+ import "eslint-import-resolver-typescript";
4
+ import type {
5
+ Linter
6
+ } from "eslint";
7
+
8
+ const configs: Linter.Config[] = [
9
+ {
10
+ files: ["**/*.ts"],
11
+ ignores: [
12
+ "dist/**",
13
+ "node_modules/**",
14
+ "main.js"
15
+ ],
16
+ languageOptions: {
17
+ parser: typescriptEslintParser,
18
+ sourceType: "module",
19
+ parserOptions: {
20
+ project: "./tsconfig.json",
21
+ ecmaVersion: 2023
22
+ }
23
+ },
24
+ plugins: {
25
+ "@typescript-eslint": typescriptEslintPlugin
26
+ },
27
+ rules: {
28
+ // Base rules
29
+ "no-unused-vars": "off",
30
+ "@typescript-eslint/no-unused-vars": ["warn", { "args": "none" }],
31
+ "@typescript-eslint/ban-ts-comment": "off",
32
+ "no-prototype-builtins": "off",
33
+ "@typescript-eslint/no-empty-function": "off",
34
+
35
+ // Useful rules but not too strict
36
+ "semi": "error",
37
+ "@typescript-eslint/explicit-function-return-type": "warn",
38
+
39
+ // Disable overly strict rules
40
+ "@typescript-eslint/no-unsafe-assignment": "off",
41
+ "@typescript-eslint/no-unsafe-call": "off",
42
+ "@typescript-eslint/no-unsafe-member-access": "off",
43
+ "@typescript-eslint/no-unsafe-argument": "off"
44
+ }
45
+ }
46
+ ];
47
+
48
+ export default configs;
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ console.log(`
4
+ Obsidian Plugin Development - Command Reference
5
+ (Run these commands from your plugin directory)
6
+
7
+ DEVELOPMENT:
8
+ yarn start Install dependencies and start development
9
+ yarn dev Build in development mode with hot reload
10
+ yarn build Build for production
11
+ yarn real Build and install in real Obsidian vault
12
+
13
+ VERSION MANAGEMENT:
14
+ yarn update-version, v Update plugin version in package.json and manifest.json
15
+ yarn release, r Create release with automated changelog
16
+
17
+ GIT OPERATIONS:
18
+ yarn acp Add, commit, and push changes
19
+ yarn bacp Build + add, commit, and push
20
+
21
+ USAGE EXAMPLES:
22
+ yarn start # First time setup
23
+ yarn dev # Daily development
24
+ yarn real # Build and test in real vault
25
+ yarn update-version # Update version before release
26
+ yarn release # Publish new version
27
+
28
+ ENVIRONMENT:
29
+ - Edit .env file to set TEST_VAULT and REAL_VAULT paths
30
+ - All scripts use centralized configuration from obsidian-plugin-config
31
+
32
+ CENTRALIZED ARCHITECTURE:
33
+ - Scripts are centralized in obsidian-plugin-config repository
34
+ - Configuration files (tsconfig, eslint) extend centralized templates
35
+ - Dependencies are managed centrally for consistency
36
+ - Run 'cd ../obsidian-plugin-config && yarn help' for migration commands
37
+
38
+ For detailed documentation: ../obsidian-plugin-config/ARCHITECTURE-SUMMARY.md
39
+ `);
@@ -0,0 +1,28 @@
1
+ {
2
+ "devDependencies": {
3
+ "@types/node": "^16.11.6",
4
+ "eslint": "^9.0.0",
5
+ "obsidian": "latest",
6
+ "obsidian-typings": "latest",
7
+ "typescript": "^5.8.2",
8
+ "tsx": "^4.19.4"
9
+ },
10
+ "engines": {
11
+ "npm": "please-use-yarn",
12
+ "yarn": ">=1.22.0"
13
+ },
14
+ "scripts": {
15
+ "start": "yarn install && yarn dev",
16
+ "dev": "tsx ../obsidian-plugin-config/scripts/esbuild.config.ts",
17
+ "build": "tsc -noEmit -skipLibCheck && tsx ../obsidian-plugin-config/scripts/esbuild.config.ts production",
18
+ "real": "tsx ../obsidian-plugin-config/scripts/esbuild.config.ts production real",
19
+ "acp": "tsx ../obsidian-plugin-config/scripts/acp.ts",
20
+ "bacp": "tsx ../obsidian-plugin-config/scripts/acp.ts -b",
21
+ "update-version": "tsx ../obsidian-plugin-config/scripts/update-version.ts",
22
+ "v": "tsx ../obsidian-plugin-config/scripts/update-version.ts",
23
+ "release": "tsx ../obsidian-plugin-config/scripts/release.ts",
24
+ "r": "tsx ../obsidian-plugin-config/scripts/release.ts",
25
+ "help": "tsx ../obsidian-plugin-config/templates/help-plugin.ts",
26
+ "h": "tsx ../obsidian-plugin-config/templates/help-plugin.ts"
27
+ }
28
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "compilerOptions": {
3
+ "types": [
4
+ "obsidian-typings"
5
+ ],
6
+ "paths": {
7
+ "obsidian-typings/implementations": [
8
+ "./node_modules/obsidian-typings/dist/implementations.d.ts",
9
+ "./node_modules/obsidian-typings/dist/implementations.cjs"
10
+ ]
11
+ },
12
+ "inlineSourceMap": true,
13
+ "inlineSources": true,
14
+ "module": "NodeNext",
15
+ "moduleResolution": "NodeNext",
16
+ "target": "ES2021",
17
+ "allowJs": true,
18
+ "noImplicitAny": true,
19
+ "importHelpers": true,
20
+ "isolatedModules": true,
21
+ "allowImportingTsExtensions": true,
22
+ "noEmit": true,
23
+ "allowSyntheticDefaultImports": true,
24
+ "verbatimModuleSyntax": true,
25
+ "forceConsistentCasingInFileNames": true,
26
+ "strictNullChecks": true,
27
+ "resolveJsonModule": true,
28
+ "lib": [
29
+ "DOM",
30
+ "ES2021"
31
+ ]
32
+ },
33
+ "include": [
34
+ "./src/**/*.ts",
35
+ "./scripts/**/*.ts"
36
+ ]
37
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "test-plugin",
3
+ "name": "Test Plugin",
4
+ "version": "1.0.0",
5
+ "minAppVersion": "0.15.0",
6
+ "description": "Plugin de test pour injection",
7
+ "author": "3C0D",
8
+ "authorUrl": "https://github.com/3C0D",
9
+ "isDesktopOnly": false
10
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "test-plugin",
3
+ "version": "1.0.0",
4
+ "description": "Plugin de test pour injection",
5
+ "main": "main.js",
6
+ "scripts": {
7
+ "dev": "tsx scripts/esbuild.config.ts",
8
+ "build": "tsc -noEmit -skipLibCheck && tsx scripts/esbuild.config.ts production",
9
+ "start": "yarn install && yarn dev",
10
+ "real": "tsx scripts/esbuild.config.ts production real",
11
+ "acp": "tsx scripts/acp.ts",
12
+ "bacp": "tsx scripts/acp.ts -b",
13
+ "update-version": "tsx scripts/update-version.ts",
14
+ "v": "tsx scripts/update-version.ts",
15
+ "release": "tsx scripts/release.ts",
16
+ "r": "tsx scripts/release.ts",
17
+ "help": "tsx scripts/help.ts",
18
+ "h": "tsx scripts/help.ts"
19
+ },
20
+ "keywords": [],
21
+ "author": "3C0D",
22
+ "license": "MIT",
23
+ "devDependencies": {
24
+ "obsidian": "latest",
25
+ "typescript": "4.7.4",
26
+ "esbuild": "0.17.3",
27
+ "dedent": "^1.5.3",
28
+ "semver": "^7.6.3",
29
+ "@types/semver": "^7.5.8",
30
+ "dotenv": "^16.4.5",
31
+ "builtin-modules": "^4.0.0",
32
+ "tsx": "^4.19.4"
33
+ },
34
+ "engines": {
35
+ "npm": "please-use-yarn",
36
+ "yarn": ">=1.22.0"
37
+ }
38
+ }
@@ -0,0 +1,71 @@
1
+ import { execSync } from "child_process";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import {
5
+ askQuestion,
6
+ cleanInput,
7
+ createReadlineInterface,
8
+ gitExec
9
+ } from "./utils.ts";
10
+
11
+ const rl = createReadlineInterface();
12
+
13
+ // Check if we're in the centralized config repo
14
+ function isInCentralizedRepo(): boolean {
15
+ const packageJsonPath = path.join(process.cwd(), "package.json");
16
+ if (!fs.existsSync(packageJsonPath)) return false;
17
+
18
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
19
+ return packageJson.name === "obsidian-plugin-config";
20
+ }
21
+
22
+ async function main(): Promise<void> {
23
+ try {
24
+ if (process.argv.includes("-b")) {
25
+ console.log("Building...");
26
+ gitExec("yarn build");
27
+ console.log("Build successful.");
28
+ }
29
+
30
+ // Only update exports if we're in the centralized repo and not explicitly disabled
31
+ if (!process.argv.includes("-ne") && !process.argv.includes("--no-exports") && isInCentralizedRepo()) {
32
+ console.log("Updating exports...");
33
+ gitExec("yarn run update-exports");
34
+ console.log("Exports updated.");
35
+ }
36
+
37
+ const input: string = await askQuestion("Enter commit message: ", rl);
38
+
39
+ const cleanedInput = cleanInput(input);
40
+
41
+ try {
42
+ gitExec("git add -A");
43
+ gitExec(`git commit -m "${cleanedInput}"`);
44
+ } catch {
45
+ console.log("Commit already exists or failed.");
46
+ return;
47
+ }
48
+
49
+ // get current branch name
50
+ const currentBranch = execSync("git rev-parse --abbrev-ref HEAD").toString().trim();
51
+
52
+ try {
53
+ gitExec(`git push origin ${currentBranch}`);
54
+ console.log("Commit and push successful.");
55
+ } catch {
56
+ // new branch
57
+ console.log(`New branch detected. Setting upstream for ${currentBranch}...`);
58
+ gitExec(`git push --set-upstream origin ${currentBranch}`);
59
+ console.log("Upstream branch set and push successful.");
60
+ }
61
+ } catch (error) {
62
+ console.error("Error:", error instanceof Error ? error.message : String(error));
63
+ } finally {
64
+ rl.close();
65
+ }
66
+ }
67
+
68
+ main().catch(console.error).finally(() => {
69
+ console.log("Exiting...");
70
+ process.exit();
71
+ });
@@ -0,0 +1,165 @@
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 { isValidPath, copyFilesToTargetDir } from "./utils.ts";
9
+
10
+ // Determine the plugin directory (where the script is called from)
11
+ const pluginDir = process.cwd();
12
+ const manifestPath = path.join(pluginDir, "manifest.json");
13
+ const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
14
+
15
+ config();
16
+
17
+ const EXTERNAL_DEPS = [
18
+ "obsidian",
19
+ "electron",
20
+ "@codemirror/autocomplete",
21
+ "@codemirror/collab",
22
+ "@codemirror/commands",
23
+ "@codemirror/language",
24
+ "@codemirror/lint",
25
+ "@codemirror/search",
26
+ "@codemirror/state",
27
+ "@codemirror/view",
28
+ "@lezer/common",
29
+ "@lezer/highlight",
30
+ "@lezer/lr",
31
+ ...builtins
32
+ ];
33
+
34
+ const BANNER = `/*
35
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
36
+ if you want to view the source, please visit the github repository of this plugin
37
+ */`;
38
+
39
+ async function validateEnvironment(): Promise<void> {
40
+ const srcMainPath = path.join(pluginDir, "src/main.ts");
41
+ if (!await isValidPath(srcMainPath)) {
42
+ throw new Error("Invalid path for src/main.ts. main.ts must be in the src directory");
43
+ }
44
+ if (!await isValidPath(manifestPath)) {
45
+ throw new Error("Invalid path for manifest.json");
46
+ }
47
+ }
48
+
49
+ function getBuildPath(isProd: boolean): string {
50
+ // If production build without redirection, return plugin directory
51
+ if (isProd && !process.argv.includes("-r")) {
52
+ return pluginDir;
53
+ }
54
+
55
+ // Determine which path to use
56
+ const envKey = process.argv.includes("-r") ? "REAL_VAULT" : "TEST_VAULT";
57
+ const vaultPath = process.env[envKey]?.trim();
58
+
59
+ // If empty or undefined, we're already in the plugin folder
60
+ if (!vaultPath) {
61
+ return pluginDir;
62
+ }
63
+
64
+ // Check if the path already contains the plugins directory path
65
+ const pluginsPath = path.join(".obsidian", "plugins");
66
+ if (vaultPath.includes(pluginsPath)) {
67
+ // Just add the manifest id to complete the path
68
+ return path.join(vaultPath, manifest.id);
69
+ }
70
+
71
+ // Otherwise, complete the full path
72
+ return path.join(vaultPath, ".obsidian", "plugins", manifest.id);
73
+ }
74
+
75
+ async function createBuildContext(buildPath: string, isProd: boolean, entryPoints: string[]): Promise<esbuild.BuildContext> {
76
+ return await esbuild.context({
77
+ banner: { js: BANNER },
78
+ minify: isProd,
79
+ entryPoints,
80
+ bundle: true,
81
+ external: EXTERNAL_DEPS,
82
+ format: "cjs",
83
+ target: "esNext",
84
+ platform: "node",
85
+ logLevel: "info",
86
+ sourcemap: isProd ? false : "inline",
87
+ treeShaking: true,
88
+ outdir: buildPath,
89
+ outbase: path.join(pluginDir, "src"),
90
+ plugins: [
91
+ // Plugin pour gérer les alias de chemin
92
+ {
93
+ name: "path-alias",
94
+ setup: (build): void => {
95
+ build.onResolve({ filter: /^@config\// }, (args) => {
96
+ const relativePath = args.path.replace(/^@config\//, "");
97
+ return {
98
+ path: path.resolve("../obsidian-plugin-config/src", relativePath)
99
+ };
100
+ });
101
+
102
+ build.onResolve({ filter: /^@config-scripts\// }, (args) => {
103
+ const relativePath = args.path.replace(/^@config-scripts\//, "");
104
+ return {
105
+ path: path.resolve("../obsidian-plugin-config/scripts", relativePath)
106
+ };
107
+ });
108
+ }
109
+ },
110
+ {
111
+ name: "copy-to-plugins-folder",
112
+ setup: (build): void => {
113
+ build.onEnd(async () => {
114
+ // if real or build
115
+ if (isProd) {
116
+ if (process.argv.includes("-r")) {
117
+ await copyFilesToTargetDir(buildPath);
118
+ console.log(`Successfully installed in ${buildPath}`);
119
+ } else {
120
+ const folderToRemove = path.join(buildPath, "_.._");
121
+ if (await isValidPath(folderToRemove)) {
122
+ await rm(folderToRemove, { recursive: true });
123
+ }
124
+ console.log("Built done in initial folder");
125
+ }
126
+ }
127
+ // if watch (dev)
128
+ else {
129
+ await copyFilesToTargetDir(buildPath);
130
+ }
131
+ });
132
+ }
133
+ }
134
+ ]
135
+ });
136
+ }
137
+
138
+ async function main(): Promise<void> {
139
+ try {
140
+ await validateEnvironment();
141
+ const isProd = process.argv[2] === "production";
142
+ const buildPath = getBuildPath(isProd);
143
+ console.log(buildPath === pluginDir
144
+ ? "Building in initial folder"
145
+ : `Building in ${buildPath}`);
146
+ const srcStylesPath = path.join(pluginDir, "src/styles.css");
147
+ const rootStylesPath = path.join(pluginDir, "styles.css");
148
+ const stylePath = await isValidPath(srcStylesPath) ? srcStylesPath : await isValidPath(rootStylesPath) ? rootStylesPath : "";
149
+ const mainTsPath = path.join(pluginDir, "src/main.ts");
150
+ const entryPoints = stylePath ? [mainTsPath, stylePath] : [mainTsPath];
151
+ const context = await createBuildContext(buildPath, isProd, entryPoints);
152
+
153
+ if (isProd) {
154
+ await context.rebuild();
155
+ process.exit(0);
156
+ } else {
157
+ await context.watch();
158
+ }
159
+ } catch (error) {
160
+ console.error("Build failed:", error);
161
+ process.exit(1);
162
+ }
163
+ }
164
+
165
+ main().catch(console.error);
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ console.log(`
4
+ Obsidian Plugin Config - Command Reference
5
+ (Run these commands from obsidian-plugin-config directory)
6
+
7
+ MIGRATION:
8
+ yarn migrate, m <path> Migrate plugin to centralized architecture
9
+ yarn migrate --dry-run Preview changes without applying (debugging)
10
+ yarn migrate -i, --interactive Interactive plugin selection
11
+
12
+ MAINTENANCE:
13
+ yarn start Install dependencies and update exports
14
+ yarn acp Add, commit, and push changes (with exports update)
15
+ yarn acp -ne, --no-exports Add, commit, and push without updating exports
16
+ yarn update-version, v Update version in centralized config
17
+ yarn help, h Show this help
18
+
19
+ USAGE EXAMPLES:
20
+ yarn migrate "C:\\Users\\dev\\plugins\\my-plugin"
21
+ yarn migrate ../existing-plugin --dry-run
22
+ yarn m -i # Short interactive mode
23
+
24
+ PATH CONVENTIONS:
25
+ - Windows absolute paths: Use quotes "C:\\path\\to\\plugin"
26
+ - Relative paths: No quotes needed ../plugin-name
27
+
28
+ For detailed documentation: ARCHITECTURE-SUMMARY.md
29
+ `);