obsidian-plugin-config 1.7.0 → 1.7.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/README.md +8 -12
- package/bin/obsidian-inject.js +2 -10
- package/docs/INTERACTIVE_INJECTION.md +55 -116
- package/docs/LLM-GUIDE.md +6 -7
- package/package.json +1 -2
- package/scripts/acp.ts +1 -1
- package/scripts/build-npm.ts +37 -28
- package/scripts/help.ts +3 -6
- package/scripts/inject-core.ts +4 -80
- package/scripts/inject-path.ts +2 -8
- package/scripts/inject-prompt.ts +2 -5
- package/templates/package-sass.json +0 -5
package/README.md
CHANGED
|
@@ -32,10 +32,6 @@ obsidian-inject ../my-plugin
|
|
|
32
32
|
# Auto-confirms all file replacements (no prompts)
|
|
33
33
|
obsidian-inject ../my-plugin --no
|
|
34
34
|
|
|
35
|
-
# Inject with SASS support
|
|
36
|
-
# Adds esbuild-sass-plugin dependency and SCSS compilation
|
|
37
|
-
obsidian-inject ../my-plugin --sass
|
|
38
|
-
|
|
39
35
|
# Verification only (dry-run)
|
|
40
36
|
# Shows what would be injected without making any changes
|
|
41
37
|
obsidian-inject ../my-plugin --dry-run
|
|
@@ -47,7 +43,6 @@ obsidian-inject --help
|
|
|
47
43
|
## CLI Options
|
|
48
44
|
|
|
49
45
|
- `--no`, `-n` - Skip confirmation prompts (auto-confirm)
|
|
50
|
-
- `--sass` - Add SASS support (esbuild-sass-plugin)
|
|
51
46
|
- `--dry-run` - Verification only (no changes)
|
|
52
47
|
|
|
53
48
|
## What is injected
|
|
@@ -61,7 +56,7 @@ obsidian-inject --help
|
|
|
61
56
|
`.env`, `.vscode/settings.json`, `.vscode/tasks.json`
|
|
62
57
|
- ✅ **GitHub Actions**: release workflow
|
|
63
58
|
- ✅ **Traceability**: `.injection-info.json` (version, date)
|
|
64
|
-
- 🎨 **
|
|
59
|
+
- 🎨 **SCSS support**: automatic detection in the injected `esbuild.config.ts`
|
|
65
60
|
|
|
66
61
|
## Commands available after injection
|
|
67
62
|
|
|
@@ -89,15 +84,17 @@ yarn upgrade # Update all dependencies to latest
|
|
|
89
84
|
|
|
90
85
|
## SASS Support
|
|
91
86
|
|
|
92
|
-
|
|
93
|
-
obsidian-inject ../my-plugin --sass
|
|
94
|
-
```
|
|
87
|
+
SCSS is detected automatically by the injected `esbuild.config.ts`:
|
|
95
88
|
|
|
96
|
-
What gets added:
|
|
97
|
-
- ✅ `esbuild-sass-plugin` dependency
|
|
98
89
|
- ✅ Automatic `.scss` detection (`src/styles.scss` priority)
|
|
99
90
|
- ✅ CSS cleanup after compilation
|
|
100
91
|
|
|
92
|
+
If your plugin uses SCSS, install the plugin once:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
yarn add -D esbuild-sass-plugin
|
|
96
|
+
```
|
|
97
|
+
|
|
101
98
|
## Architecture
|
|
102
99
|
|
|
103
100
|
Target plugins become **100% standalone** after injection:
|
|
@@ -192,7 +189,6 @@ yarn install
|
|
|
192
189
|
```bash
|
|
193
190
|
yarn inject-prompt # Interactive injection
|
|
194
191
|
yarn inject-path ../my-plugin # Direct injection
|
|
195
|
-
yarn inject ../my-plugin --sass # With SASS support
|
|
196
192
|
yarn check-plugin ../my-plugin # Dry-run only
|
|
197
193
|
```
|
|
198
194
|
|
package/bin/obsidian-inject.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Obsidian Plugin Config - CLI Entry Point
|
|
5
5
|
* Global command: obsidian-inject
|
|
6
|
-
* Version: 1.7.
|
|
6
|
+
* Version: 1.7.1
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { execSync } from 'child_process';
|
|
@@ -28,19 +28,16 @@ USAGE:
|
|
|
28
28
|
obsidian-inject # Inject in current directory (with confirmation)
|
|
29
29
|
obsidian-inject <path> # Inject by path (with confirmation)
|
|
30
30
|
obsidian-inject <path> --no # Inject without confirmation
|
|
31
|
-
obsidian-inject <path> --sass # Inject with SASS support
|
|
32
31
|
obsidian-inject --help, -h # Show this help
|
|
33
32
|
|
|
34
33
|
OPTIONS:
|
|
35
34
|
--no, -n # Skip confirmation prompts (auto-confirm all)
|
|
36
|
-
--sass # Add SASS support (esbuild-sass-plugin)
|
|
37
35
|
--dry-run # Verification only (no changes)
|
|
38
36
|
|
|
39
37
|
EXAMPLES:
|
|
40
38
|
cd my-plugin && obsidian-inject
|
|
41
39
|
obsidian-inject ../my-other-plugin
|
|
42
40
|
obsidian-inject ../my-plugin --no
|
|
43
|
-
obsidian-inject ../my-plugin --sass
|
|
44
41
|
obsidian-inject "C:\\Users\\dev\\plugins\\my-plugin"
|
|
45
42
|
|
|
46
43
|
WHAT IS INJECTED:
|
|
@@ -49,7 +46,6 @@ WHAT IS INJECTED:
|
|
|
49
46
|
✅ Config files (tsconfig, eslint, prettier, vscode, github)
|
|
50
47
|
✅ Yarn protection enforced
|
|
51
48
|
✅ Automatic dependency installation
|
|
52
|
-
🎨 SASS support (with --sass option): esbuild-sass-plugin + SCSS compilation
|
|
53
49
|
|
|
54
50
|
ARCHITECTURE:
|
|
55
51
|
- Plugin becomes AUTONOMOUS with local scripts
|
|
@@ -78,7 +74,6 @@ function main() {
|
|
|
78
74
|
|
|
79
75
|
// Parse arguments
|
|
80
76
|
const noConfirm = args.includes('--no') || args.includes('-n');
|
|
81
|
-
const sassFlag = args.includes('--sass');
|
|
82
77
|
const dryRun = args.includes('--dry-run');
|
|
83
78
|
const pathArg = args.find(arg => !arg.startsWith('-'));
|
|
84
79
|
|
|
@@ -93,7 +88,6 @@ function main() {
|
|
|
93
88
|
|
|
94
89
|
console.log(`🎯 Obsidian Plugin Config - Global Injection`);
|
|
95
90
|
console.log(`📁 Target: ${targetPath}`);
|
|
96
|
-
console.log(`🎨 SASS: ${sassFlag ? 'Enabled' : 'Disabled'}`);
|
|
97
91
|
console.log(`❓ Confirmation: ${noConfirm ? 'Disabled (auto-confirm)' : 'Enabled'}`);
|
|
98
92
|
console.log(`📦 From: ${packageRoot}\n`);
|
|
99
93
|
|
|
@@ -139,7 +133,6 @@ function main() {
|
|
|
139
133
|
}
|
|
140
134
|
|
|
141
135
|
// Check if tsx is available locally in target
|
|
142
|
-
let tsxCommand = 'npx tsx';
|
|
143
136
|
try {
|
|
144
137
|
execSync('npx tsx --version', {
|
|
145
138
|
cwd: targetPath,
|
|
@@ -164,10 +157,9 @@ function main() {
|
|
|
164
157
|
}
|
|
165
158
|
|
|
166
159
|
// Execute the injection script with tsx
|
|
167
|
-
const sassOption = sassFlag ? ' --sass' : '';
|
|
168
160
|
const yesOption = noConfirm ? ' --yes' : '';
|
|
169
161
|
const dryRunOption = dryRun ? ' --dry-run' : '';
|
|
170
|
-
const command = `npx tsx "${injectScriptPath}" "${targetPath}"${yesOption}${
|
|
162
|
+
const command = `npx tsx "${injectScriptPath}" "${targetPath}"${yesOption}${dryRunOption}`;
|
|
171
163
|
|
|
172
164
|
execSync(command, {
|
|
173
165
|
stdio: 'inherit',
|
|
@@ -1,137 +1,76 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Injection interactive
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
L'injection est **interactive par défaut** : elle compare chaque fichier du template
|
|
4
|
+
avec le fichier existant de la cible et ne demande confirmation que lorsque le contenu
|
|
5
|
+
diffère.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
## Points d'entrée
|
|
6
8
|
|
|
7
|
-
## Utilisation
|
|
8
|
-
|
|
9
|
-
### Mode par défaut (tout injecter)
|
|
10
|
-
```bash
|
|
11
|
-
obsidian-inject ../my-plugin
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
### Mode interactif (choisir quoi injecter)
|
|
15
|
-
```bash
|
|
16
|
-
obsidian-inject ../my-plugin --interactive
|
|
17
|
-
# ou
|
|
18
|
-
obsidian-inject ../my-plugin -i
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### Presets rapides
|
|
22
9
|
```bash
|
|
23
|
-
#
|
|
24
|
-
obsidian-inject
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
10
|
+
# CLI globale
|
|
11
|
+
obsidian-inject # Injection dans le dossier courant
|
|
12
|
+
obsidian-inject ../my-plugin # Injection par chemin
|
|
13
|
+
|
|
14
|
+
# Scripts locaux (développement de ce repo)
|
|
15
|
+
yarn inject-prompt # Demande le chemin du plugin cible, puis injecte
|
|
16
|
+
yarn inject-path ../my-plugin # Injection directe par chemin
|
|
17
|
+
yarn check-plugin ../my-plugin # Dry-run (vérification seule, aucune modification)
|
|
31
18
|
```
|
|
32
19
|
|
|
33
|
-
##
|
|
34
|
-
|
|
35
|
-
Le mode interactif permet de choisir :
|
|
20
|
+
## Comportement fichier par fichier
|
|
36
21
|
|
|
37
|
-
|
|
38
|
-
2. **packageJson** - package.json (scripts & dependencies)
|
|
39
|
-
3. **tsconfig** - tsconfig.json
|
|
40
|
-
4. **eslint** - eslint.config.mts
|
|
41
|
-
5. **prettier** - .prettierrc & .prettierignore
|
|
42
|
-
6. **editorconfig** - .editorconfig
|
|
43
|
-
7. **vscode** - .vscode/ (settings.json, tasks.json, extensions.json)
|
|
44
|
-
8. **github** - .github/workflows/ (release workflow)
|
|
45
|
-
9. **gitignore** - .gitignore
|
|
46
|
-
10. **env** - .env (template)
|
|
22
|
+
Pendant l'injection, chaque fichier est traité ainsi :
|
|
47
23
|
|
|
48
|
-
|
|
24
|
+
- **La cible n'existe pas encore** → le fichier est injecté sans demander.
|
|
25
|
+
- **Contenu identique** → ignoré silencieusement (`✅ ... (unchanged)`).
|
|
26
|
+
- **Contenu différent** → l'outil demande `Update <fichier>? (content differs)`.
|
|
27
|
+
- `y` → le fichier est remplacé.
|
|
28
|
+
- `n` → le fichier existant est conservé (`⏭️ Kept existing ...`).
|
|
49
29
|
|
|
50
|
-
|
|
51
|
-
- ✅ scripts
|
|
52
|
-
- ✅ packageJson
|
|
53
|
-
- ✅ env
|
|
54
|
-
- ❌ Tout le reste
|
|
30
|
+
Cas particuliers :
|
|
55
31
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
32
|
+
- `.env` est toujours **fusionné** : le template est réécrit en préservant les
|
|
33
|
+
valeurs déjà renseignées (chemins de vault, etc.).
|
|
34
|
+
- `.npmrc` est toujours injecté (protection Yarn).
|
|
35
|
+
- `eslint.config.mts` est approuvé automatiquement si un ancien `.eslintrc*`
|
|
36
|
+
est détecté (migration depuis l'ancien format).
|
|
59
37
|
|
|
60
|
-
|
|
61
|
-
- ✅ tsconfig
|
|
62
|
-
- ✅ eslint
|
|
63
|
-
- ✅ prettier
|
|
64
|
-
- ✅ editorconfig
|
|
65
|
-
- ✅ vscode
|
|
66
|
-
- ✅ gitignore
|
|
67
|
-
- ❌ scripts, packageJson, github, env
|
|
68
|
-
|
|
69
|
-
## Exemple d'Utilisation
|
|
38
|
+
## Options
|
|
70
39
|
|
|
71
40
|
```bash
|
|
72
|
-
#
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
Use default options (inject everything)? [Y/n]: n
|
|
79
|
-
|
|
80
|
-
📋 Select individual options:
|
|
81
|
-
|
|
82
|
-
Inject Scripts (esbuild.config.ts, acp.ts, utils.ts, etc.)? [Y/n]: y
|
|
83
|
-
Inject package.json (scripts & dependencies)? [Y/n]: y
|
|
84
|
-
Inject tsconfig.json? [Y/n]: n
|
|
85
|
-
Inject eslint.config.mts? [Y/n]: n
|
|
86
|
-
Inject .prettierrc & .prettierignore? [Y/n]: y
|
|
87
|
-
Inject .editorconfig? [Y/n]: y
|
|
88
|
-
Inject .vscode/ (settings.json, tasks.json, extensions.json)? [Y/n]: y
|
|
89
|
-
Inject .github/workflows/ (release workflow)? [Y/n]: n
|
|
90
|
-
Inject .gitignore? [Y/n]: y
|
|
91
|
-
Inject .env (template)? [Y/n]: y
|
|
92
|
-
|
|
93
|
-
📋 Selected options:
|
|
94
|
-
✅ Scripts (esbuild.config.ts, acp.ts, utils.ts, etc.)
|
|
95
|
-
✅ package.json (scripts & dependencies)
|
|
96
|
-
❌ tsconfig.json
|
|
97
|
-
❌ eslint.config.mts
|
|
98
|
-
✅ .prettierrc & .prettierignore
|
|
99
|
-
✅ .editorconfig
|
|
100
|
-
✅ .vscode/ (settings.json, tasks.json, extensions.json)
|
|
101
|
-
❌ .github/workflows/ (release workflow)
|
|
102
|
-
✅ .gitignore
|
|
103
|
-
✅ .env (template)
|
|
104
|
-
|
|
105
|
-
Proceed with these options? [Y/n]: y
|
|
41
|
+
# Auto-confirmer tous les remplacements (aucune question)
|
|
42
|
+
obsidian-inject ../my-plugin --no # CLI globale : --no / -n
|
|
43
|
+
yarn inject-path ../my-plugin --yes # Scripts locaux : --yes / -y
|
|
44
|
+
|
|
45
|
+
# Vérification seule (n'écrit rien)
|
|
46
|
+
obsidian-inject ../my-plugin --dry-run
|
|
106
47
|
```
|
|
107
48
|
|
|
108
|
-
|
|
49
|
+
| Option | Effet |
|
|
50
|
+
| ---------------- | -------------------------------------------------- |
|
|
51
|
+
| `--no`, `-n` | (CLI globale) auto-confirme tous les remplacements |
|
|
52
|
+
| `--yes`, `-y` | (scripts locaux) auto-confirme tous les remplacements |
|
|
53
|
+
| `--dry-run` | vérification seule, aucune modification |
|
|
109
54
|
|
|
110
|
-
|
|
111
|
-
2. **scripts/inject-prompt.ts** - Entrée interactive
|
|
112
|
-
3. **scripts/inject-path.ts** - Entrée CLI avec flags `--interactive` et `--preset`
|
|
55
|
+
## Ce qui est injecté
|
|
113
56
|
|
|
114
|
-
|
|
57
|
+
Tous les fichiers du template sont pris en compte à chaque injection (pas de
|
|
58
|
+
sélection par composant) :
|
|
115
59
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
60
|
+
- `templates/scripts/*` → `<cible>/scripts/`
|
|
61
|
+
- `templates/tsconfig.json`, `eslint.config.mts`, `.editorconfig`,
|
|
62
|
+
`.prettierrc`, `.prettierignore`, `.npmrc`, `.env`
|
|
63
|
+
- `templates/.vscode/*`
|
|
64
|
+
- `templates/.github/workflows/*`
|
|
65
|
+
- `templates/gitignore.template` → `<cible>/.gitignore`
|
|
121
66
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Tout sauf GitHub workflows
|
|
128
|
-
```bash
|
|
129
|
-
obsidian-inject ../my-plugin -i
|
|
130
|
-
# Répondre 'n' uniquement à ".github/workflows/"
|
|
131
|
-
```
|
|
67
|
+
La confirmation fichier par fichier permet de conserver un fichier existant
|
|
68
|
+
(par exemple un `esbuild.config.ts` personnalisé) en répondant `n` lorsque la
|
|
69
|
+
question apparaît.
|
|
132
70
|
|
|
133
|
-
##
|
|
71
|
+
## Fichiers concernés
|
|
134
72
|
|
|
135
|
-
-
|
|
136
|
-
|
|
137
|
-
-
|
|
73
|
+
1. **scripts/inject-core.ts** — logique d'injection (`diffAndPromptFiles`,
|
|
74
|
+
`injectScripts`, `updatePackageJson`, `performInjection`).
|
|
75
|
+
2. **scripts/inject-prompt.ts** — entrée interactive (demande le chemin).
|
|
76
|
+
3. **scripts/inject-path.ts** — entrée CLI (parse `--yes`, `--dry-run`).
|
package/docs/LLM-GUIDE.md
CHANGED
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
- `templates/scripts/` — scripts copied into `<target>/scripts/`
|
|
16
16
|
- `templates/package.json` — base deps/scripts merged into `<target>/package.json`
|
|
17
|
-
- `templates/package-sass.json` — additional deps merged when `--sass` flag is used
|
|
18
17
|
- `templates/tsconfig.json` — TypeScript config injected as `<target>/tsconfig.json`
|
|
19
18
|
- `templates/eslint.config.mts` — ESLint config injected into target
|
|
20
19
|
- `templates/.editorconfig`, `templates/.prettierrc`, etc. — config files injected into target
|
|
@@ -38,7 +37,7 @@
|
|
|
38
37
|
|
|
39
38
|
### 1. Package.json merge
|
|
40
39
|
|
|
41
|
-
`inject-core.ts → updatePackageJson()` reads `templates/package.json`
|
|
40
|
+
`inject-core.ts → updatePackageJson()` reads `templates/package.json` and merges into the target plugin's `package.json`:
|
|
42
41
|
|
|
43
42
|
- All `scripts` are overwritten with template values
|
|
44
43
|
- All `devDependencies` from template are added/updated
|
|
@@ -84,13 +83,13 @@ Scripts in `templates/scripts/` that get copied to target plugins:
|
|
|
84
83
|
|
|
85
84
|
## SASS support
|
|
86
85
|
|
|
87
|
-
|
|
86
|
+
SCSS is handled automatically by the injected `esbuild.config.ts`:
|
|
88
87
|
|
|
89
|
-
1.
|
|
90
|
-
2.
|
|
91
|
-
3. The
|
|
88
|
+
1. The build detects `.scss` files (e.g. `src/styles.scss`)
|
|
89
|
+
2. When found, it dynamically imports `esbuild-sass-plugin` and compiles the SCSS
|
|
90
|
+
3. The generated `main.css` is cleaned up after compilation
|
|
92
91
|
|
|
93
|
-
|
|
92
|
+
The `esbuild-sass-plugin` dependency is **not** injected automatically. If a plugin uses SCSS, install it once with `yarn add -D esbuild-sass-plugin` (the build prints a clear warning if it is missing). Plugins without `.scss` files build normally with no extra dependency.
|
|
94
93
|
|
|
95
94
|
---
|
|
96
95
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "obsidian-plugin-config",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Global CLI injection tool for Obsidian plugins",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"prettier": "prettier --check '**/*.{ts,json}'",
|
|
24
24
|
"prettier:fix": "prettier --write '**/*.{ts,json}'",
|
|
25
25
|
"inject-path": "tsx scripts/inject-path.ts",
|
|
26
|
-
"inject-sass": "tsx scripts/inject-path.ts --sass",
|
|
27
26
|
"inject-prompt": "tsx scripts/inject-prompt.ts",
|
|
28
27
|
"inject": "tsx scripts/inject-prompt.ts",
|
|
29
28
|
"check-plugin": "tsx scripts/inject-path.ts --dry-run",
|
package/scripts/acp.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
|
|
12
12
|
const rl = createReadlineInterface();
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/** Check if we're in the centralized config repo */
|
|
15
15
|
function isInCentralizedRepo(): boolean {
|
|
16
16
|
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
17
17
|
if (!fs.existsSync(packageJsonPath)) return false;
|
package/scripts/build-npm.ts
CHANGED
|
@@ -52,19 +52,16 @@ USAGE:
|
|
|
52
52
|
obsidian-inject # Inject in current directory (with confirmation)
|
|
53
53
|
obsidian-inject <path> # Inject by path (with confirmation)
|
|
54
54
|
obsidian-inject <path> --no # Inject without confirmation
|
|
55
|
-
obsidian-inject <path> --sass # Inject with SASS support
|
|
56
55
|
obsidian-inject --help, -h # Show this help
|
|
57
56
|
|
|
58
57
|
OPTIONS:
|
|
59
58
|
--no, -n # Skip confirmation prompts (auto-confirm all)
|
|
60
|
-
--sass # Add SASS support (esbuild-sass-plugin)
|
|
61
59
|
--dry-run # Verification only (no changes)
|
|
62
60
|
|
|
63
61
|
EXAMPLES:
|
|
64
62
|
cd my-plugin && obsidian-inject
|
|
65
63
|
obsidian-inject ../my-other-plugin
|
|
66
64
|
obsidian-inject ../my-plugin --no
|
|
67
|
-
obsidian-inject ../my-plugin --sass
|
|
68
65
|
obsidian-inject "C:\\\\Users\\\\dev\\\\plugins\\\\my-plugin"
|
|
69
66
|
|
|
70
67
|
WHAT IS INJECTED:
|
|
@@ -73,7 +70,6 @@ WHAT IS INJECTED:
|
|
|
73
70
|
✅ Config files (tsconfig, eslint, prettier, vscode, github)
|
|
74
71
|
✅ Yarn protection enforced
|
|
75
72
|
✅ Automatic dependency installation
|
|
76
|
-
🎨 SASS support (with --sass option): esbuild-sass-plugin + SCSS compilation
|
|
77
73
|
|
|
78
74
|
ARCHITECTURE:
|
|
79
75
|
- Plugin becomes AUTONOMOUS with local scripts
|
|
@@ -102,7 +98,6 @@ function main() {
|
|
|
102
98
|
|
|
103
99
|
// Parse arguments
|
|
104
100
|
const noConfirm = args.includes('--no') || args.includes('-n');
|
|
105
|
-
const sassFlag = args.includes('--sass');
|
|
106
101
|
const dryRun = args.includes('--dry-run');
|
|
107
102
|
const pathArg = args.find(arg => !arg.startsWith('-'));
|
|
108
103
|
|
|
@@ -117,7 +112,6 @@ function main() {
|
|
|
117
112
|
|
|
118
113
|
console.log(\`🎯 Obsidian Plugin Config - Global Injection\`);
|
|
119
114
|
console.log(\`📁 Target: \${targetPath}\`);
|
|
120
|
-
console.log(\`🎨 SASS: \${sassFlag ? 'Enabled' : 'Disabled'}\`);
|
|
121
115
|
console.log(\`❓ Confirmation: \${noConfirm ? 'Disabled (auto-confirm)' : 'Enabled'}\`);
|
|
122
116
|
console.log(\`📦 From: \${packageRoot}\\n\`);
|
|
123
117
|
|
|
@@ -163,7 +157,6 @@ function main() {
|
|
|
163
157
|
}
|
|
164
158
|
|
|
165
159
|
// Check if tsx is available locally in target
|
|
166
|
-
let tsxCommand = 'npx tsx';
|
|
167
160
|
try {
|
|
168
161
|
execSync('npx tsx --version', {
|
|
169
162
|
cwd: targetPath,
|
|
@@ -188,10 +181,9 @@ function main() {
|
|
|
188
181
|
}
|
|
189
182
|
|
|
190
183
|
// Execute the injection script with tsx
|
|
191
|
-
const sassOption = sassFlag ? ' --sass' : '';
|
|
192
184
|
const yesOption = noConfirm ? ' --yes' : '';
|
|
193
185
|
const dryRunOption = dryRun ? ' --dry-run' : '';
|
|
194
|
-
const command = \`npx tsx "\${injectScriptPath}" "\${targetPath}"\${yesOption}\${
|
|
186
|
+
const command = \`npx tsx "\${injectScriptPath}" "\${targetPath}"\${yesOption}\${dryRunOption}\`;
|
|
195
187
|
|
|
196
188
|
execSync(command, {
|
|
197
189
|
stdio: 'inherit',
|
|
@@ -215,33 +207,50 @@ main();
|
|
|
215
207
|
}
|
|
216
208
|
|
|
217
209
|
/**
|
|
218
|
-
*
|
|
210
|
+
* Ensure NPM authentication, prompting login if needed, then verifying success.
|
|
219
211
|
*/
|
|
220
212
|
async function ensureNpmAuth(): Promise<void> {
|
|
221
213
|
console.log(`🔐 Checking NPM authentication...`);
|
|
222
214
|
|
|
223
|
-
|
|
224
|
-
const whoami = execSync('npm whoami --registry https://registry.npmjs.org/', {
|
|
225
|
-
stdio: 'pipe',
|
|
226
|
-
encoding: 'utf8'
|
|
227
|
-
}).trim();
|
|
228
|
-
console.log(` ✅ Logged in as: ${whoami}\n`);
|
|
229
|
-
} catch {
|
|
230
|
-
console.log(` ⚠️ Not logged in to NPM\n`);
|
|
231
|
-
console.log(`🔑 Please login to NPM to publish the package`);
|
|
232
|
-
console.log(` Opening browser for authentication...\n`);
|
|
233
|
-
|
|
215
|
+
const checkWhoami = (): string | null => {
|
|
234
216
|
try {
|
|
235
|
-
execSync('npm
|
|
236
|
-
stdio: '
|
|
237
|
-
|
|
238
|
-
|
|
217
|
+
return execSync('npm whoami --registry https://registry.npmjs.org/', {
|
|
218
|
+
stdio: 'pipe',
|
|
219
|
+
encoding: 'utf8'
|
|
220
|
+
}).trim();
|
|
239
221
|
} catch {
|
|
240
|
-
|
|
241
|
-
console.error(` Please run 'npm login' manually and try again`);
|
|
242
|
-
throw new Error('NPM authentication required');
|
|
222
|
+
return null;
|
|
243
223
|
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const whoami = checkWhoami();
|
|
227
|
+
if (whoami) {
|
|
228
|
+
console.log(` ✅ Logged in as: ${whoami}\n`);
|
|
229
|
+
return;
|
|
244
230
|
}
|
|
231
|
+
|
|
232
|
+
console.log(` ⚠️ Not logged in to NPM`);
|
|
233
|
+
console.log(`🔑 Please login to NPM to publish the package`);
|
|
234
|
+
console.log(` Opening browser for authentication...\n`);
|
|
235
|
+
|
|
236
|
+
try {
|
|
237
|
+
execSync('npm login --auth-type=web --registry https://registry.npmjs.org/', {
|
|
238
|
+
stdio: 'inherit'
|
|
239
|
+
});
|
|
240
|
+
} catch {
|
|
241
|
+
console.error(`\n ❌ NPM login failed`);
|
|
242
|
+
console.error(` Please run 'npm login' manually and try again`);
|
|
243
|
+
throw new Error('NPM authentication required');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Verify login actually succeeded
|
|
247
|
+
const whoamiAfter = checkWhoami();
|
|
248
|
+
if (!whoamiAfter) {
|
|
249
|
+
console.error(`\n ❌ Login appeared to complete but authentication could not be verified`);
|
|
250
|
+
throw new Error('NPM authentication required');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
console.log(`\n ✅ Successfully logged in as: ${whoamiAfter}\n`);
|
|
245
254
|
}
|
|
246
255
|
|
|
247
256
|
/**
|
package/scripts/help.ts
CHANGED
|
@@ -18,7 +18,6 @@ LINTING:
|
|
|
18
18
|
INJECTION (local testing):
|
|
19
19
|
yarn inject-prompt # Interactive injection
|
|
20
20
|
yarn inject-path <path> # Direct injection
|
|
21
|
-
yarn inject <path> --sass # Injection with SASS support
|
|
22
21
|
yarn check-plugin <path> # Verification only (dry-run)
|
|
23
22
|
|
|
24
23
|
NPM PUBLISHING:
|
|
@@ -43,7 +42,6 @@ PURE INJECTION TOOL:
|
|
|
43
42
|
|
|
44
43
|
templates/ → what gets injected:
|
|
45
44
|
templates/package.json # Base deps/scripts for target plugins
|
|
46
|
-
templates/package-sass.json # Extra deps when --sass is used
|
|
47
45
|
templates/tsconfig.json # TypeScript config
|
|
48
46
|
templates/scripts/* # Scripts copied to target
|
|
49
47
|
templates/eslint.config.mts # ESLint config
|
|
@@ -55,7 +53,7 @@ inject-core.ts — shared injection logic:
|
|
|
55
53
|
performInjection() # Main orchestration
|
|
56
54
|
|
|
57
55
|
inject-path.ts — CLI entry point:
|
|
58
|
-
Parses --yes, --dry-run
|
|
56
|
+
Parses --yes, --dry-run flags
|
|
59
57
|
|
|
60
58
|
inject-prompt.ts — interactive entry:
|
|
61
59
|
Prompts for target path
|
|
@@ -72,7 +70,6 @@ Development:
|
|
|
72
70
|
Global CLI Usage:
|
|
73
71
|
obsidian-inject # Inject in current dir
|
|
74
72
|
obsidian-inject ../my-plugin # Inject by path
|
|
75
|
-
obsidian-inject ../my-plugin --sass # With SASS
|
|
76
73
|
obsidian-inject --help # Show help
|
|
77
74
|
|
|
78
75
|
Local Testing:
|
|
@@ -80,10 +77,10 @@ Local Testing:
|
|
|
80
77
|
yarn inject-path ../my-plugin # Direct
|
|
81
78
|
yarn check-plugin ../my-plugin # Dry-run
|
|
82
79
|
|
|
83
|
-
SASS Support (
|
|
84
|
-
✅ esbuild-sass-plugin dependency
|
|
80
|
+
SASS Support (automatic):
|
|
85
81
|
✅ Automatic .scss detection (src/styles.scss priority)
|
|
86
82
|
✅ CSS cleanup after compilation
|
|
83
|
+
💡 Install esbuild-sass-plugin manually if you use SCSS
|
|
87
84
|
|
|
88
85
|
═══════════════════════════════════════════════════════════════════
|
|
89
86
|
|
package/scripts/inject-core.ts
CHANGED
|
@@ -151,8 +151,7 @@ export async function ensurePluginConfigClean(): Promise<void> {
|
|
|
151
151
|
*/
|
|
152
152
|
export async function showInjectionPlan(
|
|
153
153
|
plan: InjectionPlan,
|
|
154
|
-
autoConfirm: boolean = false
|
|
155
|
-
useSass: boolean = false
|
|
154
|
+
autoConfirm: boolean = false
|
|
156
155
|
): Promise<boolean> {
|
|
157
156
|
const { createReadlineInterface } = await import('./utils.js');
|
|
158
157
|
const rl = createReadlineInterface();
|
|
@@ -165,9 +164,6 @@ export async function showInjectionPlan(
|
|
|
165
164
|
`📂 Scripts folder: ${plan.hasScriptsFolder ? '✅ (will be updated)' : '❌ (will be created)'}`
|
|
166
165
|
);
|
|
167
166
|
console.log(`🔌 Obsidian plugin: ${plan.isObsidianPlugin ? '✅' : '❌'}`);
|
|
168
|
-
console.log(
|
|
169
|
-
`🎨 SASS support: ${useSass ? '✅ (esbuild-sass-plugin will be added)' : '❌'}`
|
|
170
|
-
);
|
|
171
167
|
|
|
172
168
|
if (!plan.isObsidianPlugin) {
|
|
173
169
|
console.log(`\n⚠️ Warning: This doesn't appear to be a valid Obsidian plugin`);
|
|
@@ -178,7 +174,6 @@ export async function showInjectionPlan(
|
|
|
178
174
|
console.log(` ✅ Local scripts (esbuild.config.ts, utils.ts, env.ts, constants.ts, etc.)`);
|
|
179
175
|
console.log(` ✅ Updated package.json scripts`);
|
|
180
176
|
console.log(` ✅ Required dependencies`);
|
|
181
|
-
console.log(` 🔍 Analyze centralized imports (manual commenting may be needed)`);
|
|
182
177
|
|
|
183
178
|
if (autoConfirm) {
|
|
184
179
|
console.log(`\n✅ Auto-confirming all file replacements...`);
|
|
@@ -620,8 +615,7 @@ export async function injectScripts(
|
|
|
620
615
|
* Update package.json with autonomous configuration
|
|
621
616
|
*/
|
|
622
617
|
export async function updatePackageJson(
|
|
623
|
-
targetPath: string
|
|
624
|
-
useSass: boolean = false
|
|
618
|
+
targetPath: string
|
|
625
619
|
): Promise<void> {
|
|
626
620
|
const packageJsonPath = path.join(targetPath, 'package.json');
|
|
627
621
|
|
|
@@ -638,13 +632,6 @@ export async function updatePackageJson(
|
|
|
638
632
|
fs.readFileSync(path.join(configRoot, 'templates/package.json'), 'utf8')
|
|
639
633
|
);
|
|
640
634
|
|
|
641
|
-
if (useSass) {
|
|
642
|
-
const sassPkg = JSON.parse(
|
|
643
|
-
fs.readFileSync(path.join(configRoot, 'templates/package-sass.json'), 'utf8')
|
|
644
|
-
);
|
|
645
|
-
Object.assign(templatePkg.devDependencies, sassPkg.devDependencies);
|
|
646
|
-
}
|
|
647
|
-
|
|
648
635
|
const obsoleteScripts = ['version'];
|
|
649
636
|
for (const script of obsoleteScripts) {
|
|
650
637
|
if (packageJson.scripts?.[script]) {
|
|
@@ -688,66 +675,6 @@ export async function updatePackageJson(
|
|
|
688
675
|
}
|
|
689
676
|
}
|
|
690
677
|
|
|
691
|
-
/**
|
|
692
|
-
* Analyze centralized imports in source files (without modifying)
|
|
693
|
-
*/
|
|
694
|
-
export async function analyzeCentralizedImports(targetPath: string): Promise<void> {
|
|
695
|
-
const srcPath = path.join(targetPath, 'src');
|
|
696
|
-
|
|
697
|
-
if (!(await isValidPath(srcPath))) {
|
|
698
|
-
console.log(` ℹ️ No src directory found`);
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
console.log(`\n🔍 Analyzing centralized imports...`);
|
|
703
|
-
|
|
704
|
-
try {
|
|
705
|
-
const findTsFiles = (dir: string): string[] => {
|
|
706
|
-
const files: string[] = [];
|
|
707
|
-
for (const item of fs.readdirSync(dir)) {
|
|
708
|
-
const fullPath = path.join(dir, item);
|
|
709
|
-
if (fs.statSync(fullPath).isDirectory()) {
|
|
710
|
-
files.push(...findTsFiles(fullPath));
|
|
711
|
-
} else if (item.endsWith('.ts') || item.endsWith('.tsx')) {
|
|
712
|
-
files.push(fullPath);
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
return files;
|
|
716
|
-
};
|
|
717
|
-
|
|
718
|
-
const tsFiles = findTsFiles(srcPath);
|
|
719
|
-
let filesWithImports = 0;
|
|
720
|
-
|
|
721
|
-
for (const filePath of tsFiles) {
|
|
722
|
-
try {
|
|
723
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
724
|
-
const importRegex = /import\s+.*from\s+["']obsidian-plugin-config[^"']*["']/g;
|
|
725
|
-
if (importRegex.test(content)) {
|
|
726
|
-
filesWithImports++;
|
|
727
|
-
console.log(
|
|
728
|
-
` ⚠️ ${path.relative(targetPath, filePath)} - contains centralized imports`
|
|
729
|
-
);
|
|
730
|
-
}
|
|
731
|
-
} catch (error) {
|
|
732
|
-
console.warn(
|
|
733
|
-
` ⚠️ Could not analyze ${path.relative(targetPath, filePath)}: ${error}`
|
|
734
|
-
);
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
if (filesWithImports === 0) {
|
|
739
|
-
console.log(` ✅ No centralized imports found`);
|
|
740
|
-
} else {
|
|
741
|
-
console.log(` ⚠️ Found ${filesWithImports} files with centralized imports`);
|
|
742
|
-
console.log(
|
|
743
|
-
` 💡 You may need to manually comment these imports for the plugin to work`
|
|
744
|
-
);
|
|
745
|
-
}
|
|
746
|
-
} catch (error) {
|
|
747
|
-
console.error(` ❌ Failed to analyze imports: ${error}`);
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
|
|
751
678
|
/**
|
|
752
679
|
* Create required directories
|
|
753
680
|
*/
|
|
@@ -922,8 +849,7 @@ export async function runYarnInstall(targetPath: string): Promise<void> {
|
|
|
922
849
|
*/
|
|
923
850
|
export async function performInjection(
|
|
924
851
|
targetPath: string,
|
|
925
|
-
autoConfirm: boolean = false
|
|
926
|
-
useSass: boolean = false
|
|
852
|
+
autoConfirm: boolean = false
|
|
927
853
|
): Promise<void> {
|
|
928
854
|
console.log(`\n🚀 Starting injection process...`);
|
|
929
855
|
|
|
@@ -934,9 +860,7 @@ export async function performInjection(
|
|
|
934
860
|
await injectScripts(targetPath, approvedDests);
|
|
935
861
|
|
|
936
862
|
console.log(`\n📦 Updating package.json...`);
|
|
937
|
-
await updatePackageJson(targetPath
|
|
938
|
-
|
|
939
|
-
await analyzeCentralizedImports(targetPath);
|
|
863
|
+
await updatePackageJson(targetPath);
|
|
940
864
|
|
|
941
865
|
console.log(`\n📁 Creating required directories...`);
|
|
942
866
|
await createRequiredDirectories(targetPath);
|
package/scripts/inject-path.ts
CHANGED
|
@@ -32,7 +32,6 @@ async function main(): Promise<void> {
|
|
|
32
32
|
const args = process.argv.slice(2);
|
|
33
33
|
const autoConfirm = args.includes('--yes') || args.includes('-y');
|
|
34
34
|
const dryRun = args.includes('--dry-run') || args.includes('--check');
|
|
35
|
-
const useSass = args.includes('--sass');
|
|
36
35
|
const targetPath = args.find((arg) => !arg.startsWith('-'));
|
|
37
36
|
|
|
38
37
|
if (!targetPath) {
|
|
@@ -41,7 +40,6 @@ async function main(): Promise<void> {
|
|
|
41
40
|
console.error(` Options:`);
|
|
42
41
|
console.error(` --yes, -y Auto-confirm injection`);
|
|
43
42
|
console.error(` --dry-run Check only (no injection)`);
|
|
44
|
-
console.error(` --sass Add esbuild-sass-plugin dependency`);
|
|
45
43
|
console.error(` Shortcuts:`);
|
|
46
44
|
console.error(` yarn check-plugin ../plugin # Verification only`);
|
|
47
45
|
process.exit(1);
|
|
@@ -77,9 +75,6 @@ async function main(): Promise<void> {
|
|
|
77
75
|
`📂 Scripts folder: ${plan.hasScriptsFolder ? '✅ (will be updated)' : '❌ (will be created)'}`
|
|
78
76
|
);
|
|
79
77
|
console.log(`🔌 Obsidian plugin: ${plan.isObsidianPlugin ? '✅' : '❌'}`);
|
|
80
|
-
console.log(
|
|
81
|
-
`🎨 SASS support: ${useSass ? '✅ (esbuild-sass-plugin will be added)' : '❌'}`
|
|
82
|
-
);
|
|
83
78
|
|
|
84
79
|
if (!plan.isObsidianPlugin) {
|
|
85
80
|
console.log(`\n⚠️ Warning: This doesn't appear to be a valid Obsidian plugin`);
|
|
@@ -90,7 +85,6 @@ async function main(): Promise<void> {
|
|
|
90
85
|
console.log(` ✅ Local scripts (utils.ts, esbuild.config.ts, acp.ts, etc.)`);
|
|
91
86
|
console.log(` ✅ Updated package.json scripts`);
|
|
92
87
|
console.log(` ✅ Required dependencies`);
|
|
93
|
-
console.log(` 🔍 Analyze centralized imports (manual commenting may be needed)`);
|
|
94
88
|
|
|
95
89
|
const injectionInfo = readInjectionInfo(resolvedPath);
|
|
96
90
|
|
|
@@ -145,14 +139,14 @@ async function main(): Promise<void> {
|
|
|
145
139
|
console.log(`\n🔍 Checking plugin-config repository status...`);
|
|
146
140
|
await ensurePluginConfigClean();
|
|
147
141
|
|
|
148
|
-
const confirmed = await showInjectionPlan(plan, autoConfirm
|
|
142
|
+
const confirmed = await showInjectionPlan(plan, autoConfirm);
|
|
149
143
|
|
|
150
144
|
if (!confirmed) {
|
|
151
145
|
console.log(`❌ Injection cancelled by user`);
|
|
152
146
|
process.exit(0);
|
|
153
147
|
}
|
|
154
148
|
|
|
155
|
-
await performInjection(resolvedPath, autoConfirm
|
|
149
|
+
await performInjection(resolvedPath, autoConfirm);
|
|
156
150
|
} catch (error) {
|
|
157
151
|
console.error(`💥 Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
158
152
|
process.exit(1);
|
package/scripts/inject-prompt.ts
CHANGED
|
@@ -21,8 +21,6 @@ async function promptForTargetPath(): Promise<string> {
|
|
|
21
21
|
console.log(`\n📁 Select target plugin directory:`);
|
|
22
22
|
console.log(` Common paths (copy-paste ready):`);
|
|
23
23
|
console.log(` - ../test-sample-plugin`);
|
|
24
|
-
console.log(` - ../sample-plugin-modif`);
|
|
25
|
-
console.log(` - ../my-obsidian-plugin`);
|
|
26
24
|
console.log(` 💡 Tip: You can paste paths with or without quotes`);
|
|
27
25
|
|
|
28
26
|
while (true) {
|
|
@@ -54,7 +52,6 @@ async function main(): Promise<void> {
|
|
|
54
52
|
console.log(`📥 Inject autonomous configuration with prompts\n`);
|
|
55
53
|
|
|
56
54
|
const args = process.argv.slice(2);
|
|
57
|
-
const useSass = args.includes('--sass');
|
|
58
55
|
let targetPath: string;
|
|
59
56
|
|
|
60
57
|
const pathArg = args.find((arg) => !arg.startsWith('-'));
|
|
@@ -88,14 +85,14 @@ async function main(): Promise<void> {
|
|
|
88
85
|
console.log(`\n🔍 Analyzing plugin...`);
|
|
89
86
|
const plan = await analyzePlugin(targetPath);
|
|
90
87
|
|
|
91
|
-
const confirmed = await showInjectionPlan(plan, false
|
|
88
|
+
const confirmed = await showInjectionPlan(plan, false);
|
|
92
89
|
|
|
93
90
|
if (!confirmed) {
|
|
94
91
|
console.log(`❌ Injection cancelled by user`);
|
|
95
92
|
process.exit(0);
|
|
96
93
|
}
|
|
97
94
|
|
|
98
|
-
await performInjection(targetPath, false
|
|
95
|
+
await performInjection(targetPath, false);
|
|
99
96
|
} catch (error) {
|
|
100
97
|
console.error(`💥 Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
101
98
|
process.exit(1);
|