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.
- package/.vscode/settings.json +4 -0
- package/README.md +45 -0
- package/bin/obsidian-inject.js +98 -0
- package/obsidian-plugin-config-1.0.2.tgz +0 -0
- package/package.json +88 -0
- package/scripts/acp.ts +71 -0
- package/scripts/build-npm.ts +137 -0
- package/scripts/esbuild.config.ts +311 -0
- package/scripts/help.ts +46 -0
- package/scripts/inject-path.ts +487 -0
- package/scripts/inject-prompt.ts +399 -0
- package/scripts/open-editor.mjs +18 -0
- package/scripts/release.ts +97 -0
- package/scripts/update-exports.js +91 -0
- package/scripts/update-version-config.ts +98 -0
- package/scripts/update-version.ts +102 -0
- package/scripts/utils.ts +117 -0
- package/src/index.ts +6 -0
- package/src/main_test.ts +106 -0
- package/src/modals/GenericConfirmModal.ts +67 -0
- package/src/modals/index.ts +3 -0
- package/src/test-centralized-utils.ts +23 -0
- package/src/tools/index.ts +9 -0
- package/src/utils/NoticeHelper.ts +102 -0
- package/src/utils/SettingsHelper.ts +180 -0
- package/src/utils/index.ts +3 -0
- package/templates/.vscode/settings.json +4 -0
- package/templates/eslint.config.ts +48 -0
- package/templates/help-plugin.ts +39 -0
- package/templates/package-versions.json +28 -0
- package/templates/tsconfig.json +37 -0
- package/test-plugin/manifest.json +10 -0
- package/test-plugin/package.json +38 -0
- package/test-plugin/scripts/acp.ts +71 -0
- package/test-plugin/scripts/esbuild.config.ts +165 -0
- package/test-plugin/scripts/help.ts +29 -0
- package/test-plugin/scripts/release.ts +97 -0
- package/test-plugin/scripts/update-version.ts +102 -0
- package/test-plugin/scripts/utils.ts +117 -0
- package/test-plugin/src/main.ts +11 -0
- package/test-plugin/yarn.lock +386 -0
- package/test-plugin-v2/main.js +5 -0
- package/test-plugin-v2/manifest.json +10 -0
- package/test-plugin-v2/package.json +40 -0
- package/test-plugin-v2/scripts/acp.ts +71 -0
- package/test-plugin-v2/scripts/esbuild.config.ts +165 -0
- package/test-plugin-v2/scripts/help.ts +29 -0
- package/test-plugin-v2/scripts/release.ts +97 -0
- package/test-plugin-v2/scripts/update-version.ts +102 -0
- package/test-plugin-v2/scripts/utils.ts +117 -0
- package/test-plugin-v2/src/main.ts +11 -0
- package/test-plugin-v2/tsconfig.json +31 -0
- package/test-plugin-v2/yarn.lock +1986 -0
- package/tsconfig.json +38 -0
- 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,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,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
|
+
`);
|