obsidian-plugin-config 1.7.2 → 1.7.3
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/bin/obsidian-inject.js +1 -1
- package/docs/INTERACTIVE_INJECTION.md +1 -1
- package/docs/LLM-GUIDE.md +8 -7
- package/docs/SCSS-FLOW.md +273 -0
- package/docs/audit.md +39 -0
- package/package.json +7 -1
- package/scripts/acp.ts +5 -2
- package/scripts/help.ts +2 -2
- package/scripts/inject-core.ts +20 -19
- package/scripts/utils.ts +2 -2
- package/templates/.github/workflows/release.yml +2 -2
- package/templates/{package.json → package.json.template} +1 -1
- package/templates/scripts/acp.ts +5 -2
- package/templates/scripts/esbuild.config.ts +3 -3
- package/templates/scripts/utils.ts +13 -12
- package/tsconfig.json +2 -2
- /package/templates/{tsconfig.json → tsconfig.json.template} +0 -0
package/bin/obsidian-inject.js
CHANGED
|
@@ -58,7 +58,7 @@ Tous les fichiers du template sont pris en compte à chaque injection (pas de
|
|
|
58
58
|
sélection par composant) :
|
|
59
59
|
|
|
60
60
|
- `templates/scripts/*` → `<cible>/scripts/`
|
|
61
|
-
- `templates/tsconfig.json`, `eslint.config.mts`, `.editorconfig`,
|
|
61
|
+
- `templates/tsconfig.json.template`, `eslint.config.mts`, `.editorconfig`,
|
|
62
62
|
`.prettierrc`, `.prettierignore`, `.npmrc`, `.env`
|
|
63
63
|
- `templates/.vscode/*`
|
|
64
64
|
- `templates/.github/workflows/*`
|
package/docs/LLM-GUIDE.md
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
`templates/` contains everything that gets injected into target plugins:
|
|
14
14
|
|
|
15
15
|
- `templates/scripts/` — scripts copied into `<target>/scripts/`
|
|
16
|
-
- `templates/package.json` — base deps/scripts merged into `<target>/package.json`
|
|
17
|
-
- `templates/tsconfig.json` — TypeScript config injected as `<target>/tsconfig.json`
|
|
16
|
+
- `templates/package.json.template` — base deps/scripts merged into `<target>/package.json`
|
|
17
|
+
- `templates/tsconfig.json.template` — TypeScript config injected as `<target>/tsconfig.json`
|
|
18
18
|
- `templates/eslint.config.mts` — ESLint config injected into target
|
|
19
19
|
- `templates/.editorconfig`, `templates/.prettierrc`, etc. — config files injected into target
|
|
20
20
|
- `templates/.github/workflows/` — GitHub Actions workflows
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
### 1. Package.json merge
|
|
39
39
|
|
|
40
|
-
`inject-core.ts → updatePackageJson()` reads `templates/package.json` and merges into the target plugin's `package.json`:
|
|
40
|
+
`inject-core.ts → updatePackageJson()` reads `templates/package.json.template` and merges into the target plugin's `package.json`:
|
|
41
41
|
|
|
42
42
|
- All `scripts` are overwritten with template values
|
|
43
43
|
- All `devDependencies` from template are added/updated
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
- `templates/scripts/*` → `<target>/scripts/`
|
|
52
52
|
- `templates/tsconfig.json` → `<target>/tsconfig.json`
|
|
53
53
|
- `templates/eslint.config.mts` → `<target>/eslint.config.mts`
|
|
54
|
-
- `templates/.editorconfig`, `.prettierrc`, `.npmrc`, `.env` → `<target>/`
|
|
54
|
+
- `templates/.editorconfig`, `.prettierrc`, `.npmrc`, `.env`, `.gitattributes` → `<target>/`
|
|
55
|
+
- `templates/.vscode/*` → `<target>/.vscode/`
|
|
55
56
|
- `templates/.github/workflows/*` → `<target>/.github/workflows/`
|
|
56
57
|
- `templates/gitignore.template` → `<target>/.gitignore`
|
|
57
58
|
|
|
@@ -95,9 +96,9 @@ The `esbuild-sass-plugin` dependency is **not** injected automatically. If a plu
|
|
|
95
96
|
|
|
96
97
|
## What NOT to do
|
|
97
98
|
|
|
98
|
-
- ❌ Do not hardcode deps/scripts in `inject-core.ts` — they must come from `templates/package.json`
|
|
99
|
+
- ❌ Do not hardcode deps/scripts in `inject-core.ts` — they must come from `templates/package.json.template`
|
|
99
100
|
- ❌ Do not modify root config files thinking it will affect injected plugins — always modify `templates/`
|
|
100
|
-
- ❌ Do not add `obsidian-plugin-config` as a dependency in `templates/package.json` — injected plugins are standalone
|
|
101
|
+
- ❌ Do not add `obsidian-plugin-config` as a dependency in `templates/package.json.template` — injected plugins are standalone
|
|
101
102
|
- ❌ Do not inject `esbuild.config.ts` without its dependencies (`constants.ts`, `env.ts`, `reload.ts`, `typingsPlugin.ts`, `utils.ts`) — they are all required
|
|
102
103
|
|
|
103
104
|
---
|
|
@@ -115,7 +116,7 @@ To change what gets injected:
|
|
|
115
116
|
|
|
116
117
|
## obsidian-typings paths
|
|
117
118
|
|
|
118
|
-
The correct paths for `obsidian-typings` in `templates/tsconfig.json`:
|
|
119
|
+
The correct paths for `obsidian-typings` in `templates/tsconfig.json.template`:
|
|
119
120
|
|
|
120
121
|
```json
|
|
121
122
|
"types": ["obsidian-typings"],
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Comment fonctionne SCSS dans cette config
|
|
2
|
+
|
|
3
|
+
Ce document explique de bout en bout comment un fichier `.scss` est détecté, compilé puis copié dans le dossier `plugins` d'Obsidian, en s'appuyant sur le code du dépôt.
|
|
4
|
+
|
|
5
|
+
> Remarque : la configuration SCSS n'est pas activée dans `obsidian-plugin-config` lui-même. Elle est définie dans les **templates** qui sont copiés dans chaque plugin Obsidian lors de l'injection (`yarn inject` / `obsidian-inject`). Tout le code cité ci-dessous vit donc dans `templates/scripts/`.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Vue d'ensemble du flux
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
src/styles.scss
|
|
13
|
+
│
|
|
14
|
+
│ détection (esbuild.config.ts → main())
|
|
15
|
+
▼
|
|
16
|
+
entryPoints = [src/main.ts, src/styles.scss]
|
|
17
|
+
│
|
|
18
|
+
│ esbuild.context() + sassPlugin() (esbuild.config.ts → createBuildContext)
|
|
19
|
+
▼
|
|
20
|
+
buildPath/<id>/
|
|
21
|
+
├── main.js
|
|
22
|
+
└── main.css ← produit par esbuild-sass-plugin
|
|
23
|
+
│
|
|
24
|
+
│ plugin "remove-main-css" (esbuild.config.ts) → utils.removeMainCss
|
|
25
|
+
│ + plugin "copy-to-plugins-folder" (esbuild.config.ts) → utils.copyFilesToTargetDir
|
|
26
|
+
▼
|
|
27
|
+
buildPath/<id>/
|
|
28
|
+
├── manifest.json (copié)
|
|
29
|
+
├── main.js
|
|
30
|
+
└── styles.css ← renommé depuis main.css ? non : voir point 3
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Les deux moments clés sont :
|
|
34
|
+
|
|
35
|
+
1. **Détection et compilation** dans `templates/scripts/esbuild.config.ts`.
|
|
36
|
+
2. **Nettoyage et copie vers le dossier plugins** via les fonctions utilitaires de `templates/scripts/utils.ts`.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 2. Où passe le fichier SCSS
|
|
41
|
+
|
|
42
|
+
### 2.1 Détection du fichier SCSS
|
|
43
|
+
|
|
44
|
+
Dans `templates/scripts/esbuild.config.ts`, fonction `main()` (lignes 115-140) :
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// Check for SCSS first, then CSS in src, then in root
|
|
48
|
+
const srcStylesScssPath = path.join(pluginDir, 'src/styles.scss');
|
|
49
|
+
const srcStylesPath = path.join(pluginDir, 'src/styles.css');
|
|
50
|
+
const rootStylesPath = path.join(pluginDir, 'styles.css');
|
|
51
|
+
|
|
52
|
+
const scssExists = await isValidPath(srcStylesScssPath);
|
|
53
|
+
const stylePath = scssExists
|
|
54
|
+
? srcStylesScssPath
|
|
55
|
+
: (await isValidPath(srcStylesPath))
|
|
56
|
+
? srcStylesPath
|
|
57
|
+
: (await isValidPath(rootStylesPath))
|
|
58
|
+
? rootStylesPath
|
|
59
|
+
: '';
|
|
60
|
+
|
|
61
|
+
const mainTsPath = path.join(pluginDir, 'src/main.ts');
|
|
62
|
+
const entryPoints = stylePath ? [mainTsPath, stylePath] : [mainTsPath];
|
|
63
|
+
const context = await createBuildContext(buildPath, isProd, entryPoints, scssExists);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Le fichier SCSS est donc attendu à `src/styles.scss` (priorité maximale).
|
|
67
|
+
- Sinon, fallback sur `src/styles.css` puis `styles.css` à la racine.
|
|
68
|
+
- `scssExists` (booléen) sert ensuite à activer ou non le plugin SASS dans esbuild.
|
|
69
|
+
|
|
70
|
+
### 2.2 Compilation via esbuild + sassPlugin
|
|
71
|
+
|
|
72
|
+
Toujours dans `templates/scripts/esbuild.config.ts`, fonction `createBuildContext()` (lignes 33-69) :
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const plugins = [
|
|
76
|
+
// Add SASS plugin if SCSS files are detected
|
|
77
|
+
...(hasSass
|
|
78
|
+
? [
|
|
79
|
+
await (async () => {
|
|
80
|
+
try {
|
|
81
|
+
// @ts-expect-error - esbuild-sass-plugin is installed during injection
|
|
82
|
+
const { sassPlugin } = await import('esbuild-sass-plugin');
|
|
83
|
+
return sassPlugin({
|
|
84
|
+
syntax: 'scss',
|
|
85
|
+
style: 'expanded'
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.warn(
|
|
89
|
+
'⚠️ esbuild-sass-plugin not found. Install it with: yarn add -D esbuild-sass-plugin'
|
|
90
|
+
);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
})(),
|
|
94
|
+
{
|
|
95
|
+
name: 'remove-main-css',
|
|
96
|
+
setup(build: esbuild.PluginBuild): void {
|
|
97
|
+
build.onEnd(async (result) => {
|
|
98
|
+
if (result.errors.length === 0) {
|
|
99
|
+
await removeMainCss(buildPath);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
: []),
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- Le `sassPlugin` n'est importé que si `hasSass` est `true` (donc si `src/styles.scss` existe).
|
|
109
|
+
- Il est configuré en syntaxe `scss` et style `expanded` (non minifié, lisible).
|
|
110
|
+
- esbuild produit un fichier `main.css` à côté de `main.js` dans `outdir` (= `buildPath`).
|
|
111
|
+
- Un second plugin esbuild interne, `remove-main-css`, supprime ce `main.css` à la fin du build (voir 3.1).
|
|
112
|
+
|
|
113
|
+
### 2.3 Dépendance : `esbuild-sass-plugin`
|
|
114
|
+
|
|
115
|
+
- Import dynamique, donc l'installation de la dépendance n'est pas obligatoire pour les plugins qui n'utilisent pas SCSS.
|
|
116
|
+
- Le code affiche un warning et échoue si SCSS est détecté mais que le plugin n'est pas installé :
|
|
117
|
+
|
|
118
|
+
> `⚠️ esbuild-sass-plugin not found. Install it with: yarn add -D esbuild-sass-plugin`
|
|
119
|
+
|
|
120
|
+
- Côté utilisateur, la doc le précise : `README.md`, section **SASS Support** (lignes 85-96).
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 3. Comment c'est copié dans le dossier plugins
|
|
125
|
+
|
|
126
|
+
### 3.1 Nettoyage du `main.css` parasite
|
|
127
|
+
|
|
128
|
+
Dans `templates/scripts/utils.ts`, fonction `removeMainCss()` (lignes 169-180) :
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
export async function removeMainCss(outdir: string): Promise<void> {
|
|
132
|
+
const mainCssPath = path.join(outdir, 'main.css');
|
|
133
|
+
try {
|
|
134
|
+
await rm(mainCssPath);
|
|
135
|
+
} catch (error: unknown) {
|
|
136
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
|
|
137
|
+
console.warn(
|
|
138
|
+
`Warning: Could not remove main.css: ${error instanceof Error ? error.message : String(error)}`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Pourquoi ? Le `sassPlugin` d'esbuild génère un fichier `main.css` parce qu'il hérite du `name` (`main`) de l'entry point. Or Obsidian attend `styles.css` dans le dossier du plugin. `removeMainCss` supprime donc ce fichier temporaire immédiatement après chaque build (uniquement si le build n'a pas d'erreur, cf. `if (result.errors.length === 0)` dans `esbuild.config.ts`).
|
|
146
|
+
|
|
147
|
+
### 3.2 Copie vers le dossier plugins
|
|
148
|
+
|
|
149
|
+
Dans `templates/scripts/utils.ts`, fonction `copyFilesToTargetDir()` (lignes 74-123) :
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
export async function copyFilesToTargetDir(buildPath: string): Promise<void> {
|
|
153
|
+
const pluginDir = process.cwd();
|
|
154
|
+
const manifestSrc = path.join(pluginDir, 'manifest.json');
|
|
155
|
+
const manifestDest = path.join(buildPath, 'manifest.json');
|
|
156
|
+
const cssDest = path.join(buildPath, 'styles.css');
|
|
157
|
+
const folderToRemove = path.join(buildPath, '_.._');
|
|
158
|
+
...
|
|
159
|
+
// Copy CSS
|
|
160
|
+
try {
|
|
161
|
+
const srcStylesPath = path.join(pluginDir, 'src/styles.css');
|
|
162
|
+
const rootStylesPath = path.join(pluginDir, 'styles.css');
|
|
163
|
+
|
|
164
|
+
if (await isValidPath(srcStylesPath)) {
|
|
165
|
+
await copyFile(srcStylesPath, cssDest);
|
|
166
|
+
}
|
|
167
|
+
else if (await isValidPath(rootStylesPath)) {
|
|
168
|
+
await copyFile(rootStylesPath, cssDest);
|
|
169
|
+
if (await isValidPath(folderToRemove)) {
|
|
170
|
+
await rm(folderToRemove, { recursive: true });
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
} ...
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
> Note importante : `copyFilesToTargetDir` ne copie **que** `manifest.json` et un éventuel `styles.css` / `styles.css` racine. Le `main.css` généré par esbuild-sass-plugin est supprimé à l'étape précédente (3.1).
|
|
180
|
+
|
|
181
|
+
### 3.3 Branchement sur le cycle de vie esbuild
|
|
182
|
+
|
|
183
|
+
Toujours dans `templates/scripts/esbuild.config.ts`, le plugin `copy-to-plugins-folder` (lignes 70-94) déclenche la copie après chaque build :
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
{
|
|
187
|
+
name: 'copy-to-plugins-folder',
|
|
188
|
+
setup: (build: esbuild.PluginBuild): void => {
|
|
189
|
+
build.onEnd(async () => {
|
|
190
|
+
if (isProd) {
|
|
191
|
+
if (process.argv.includes('-r') || process.argv.includes('real')) {
|
|
192
|
+
await copyFilesToTargetDir(buildPath);
|
|
193
|
+
console.log(`Successfully installed in ${buildPath}`);
|
|
194
|
+
await reloadObsidian();
|
|
195
|
+
} else {
|
|
196
|
+
const folderToRemove = path.join(buildPath, '_.._');
|
|
197
|
+
if (await isValidPath(folderToRemove)) {
|
|
198
|
+
await rm(folderToRemove, { recursive: true });
|
|
199
|
+
}
|
|
200
|
+
console.log('Build done in initial folder');
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
// watch (dev)
|
|
204
|
+
await copyFilesToTargetDir(buildPath);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- Mode **dev (`yarn dev`)** : après chaque rebuild (watch), `copyFilesToTargetDir` recopie manifest + CSS vers le vault de test.
|
|
212
|
+
- Mode **build prod (`yarn build`)** : rien n'est copié par défaut, sauf si on passe `-r` / `real` (=> copie vers le vault de prod + reload Obsidian).
|
|
213
|
+
|
|
214
|
+
### 3.4 Cible : `buildPath`
|
|
215
|
+
|
|
216
|
+
`buildPath` est calculé par `env.ts` (`getBuildPath`) à partir de `.env` (`TEST_VAULT` / `REAL_VAULT`) ou du dossier courant (développement in-place). Il pointe vers :
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
<vault>/.obsidian/plugins/<pluginId>/
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Donc concrètement, le résultat final pour le SCSS est :
|
|
223
|
+
|
|
224
|
+
1. `src/styles.scss` → compilé par esbuild-sass-plugin → `buildPath/main.css` (transitoire)
|
|
225
|
+
2. `main.css` renommé en `styles.css` par `renameMainCss`
|
|
226
|
+
3. Le CSS est directement disponible et référencé via `manifest.json` (`"css": "styles.css"`).
|
|
227
|
+
|
|
228
|
+
> 💡 Le `styles.css` final est produit automatiquement par ce pipeline en renommant le fichier `main.css` issu de la compilation SCSS. Aucun fichier source `styles.css` n'est nécessaire à la racine si vous utilisez exclusivement du SCSS.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## 4. Où l'injecteur installe tout ça dans le plugin cible
|
|
233
|
+
|
|
234
|
+
L'injection des templates se fait dans `scripts/inject-core.ts`, fonction `injectScripts()` (lignes 455-612). Le tableau `scriptFiles` (lignes 469-480) liste explicitement les fichiers copiés dans le dossier `scripts/` du plugin cible :
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
const scriptFiles = [
|
|
238
|
+
'templates/scripts/utils.ts',
|
|
239
|
+
'templates/scripts/esbuild.config.ts',
|
|
240
|
+
'templates/scripts/acp.ts',
|
|
241
|
+
'templates/scripts/update-version.ts',
|
|
242
|
+
'templates/scripts/release.ts',
|
|
243
|
+
'templates/scripts/help.ts',
|
|
244
|
+
'templates/scripts/constants.ts',
|
|
245
|
+
'templates/scripts/env.ts',
|
|
246
|
+
'templates/scripts/reload.ts',
|
|
247
|
+
'templates/scripts/typingsPlugin.ts'
|
|
248
|
+
];
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Donc après injection, le plugin Obsidian cible contient `scripts/esbuild.config.ts` (avec la logique SCSS) et `scripts/utils.ts` (avec `removeMainCss` et `copyFilesToTargetDir`).
|
|
252
|
+
|
|
253
|
+
Le `.gitignore` injecté (`templates/gitignore.template`, ligne 25-26) ignore explicitement le fichier intermédiaire :
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
# scss result
|
|
257
|
+
main.css
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## 5. Récapitulatif des fichiers clés
|
|
263
|
+
|
|
264
|
+
| Rôle | Fichier | Fonctions / lignes |
|
|
265
|
+
|------|---------|--------------------|
|
|
266
|
+
| Détection SCSS + build esbuild | `templates/scripts/esbuild.config.ts` | `main()` ~l. 115-140, `createBuildContext()` ~l. 33-69 |
|
|
267
|
+
| Plugin esbuild pour compiler SCSS | `esbuild-sass-plugin` (importé dynamiquement) | `esbuild.config.ts` ~l. 41-58 |
|
|
268
|
+
| Suppression du `main.css` transitoire | `templates/scripts/utils.ts` | `removeMainCss()` ~l. 169-180 |
|
|
269
|
+
| Copie finale vers le dossier plugins | `templates/scripts/utils.ts` | `copyFilesToTargetDir()` ~l. 74-123 |
|
|
270
|
+
| Branchement sur `onEnd` esbuild | `templates/scripts/esbuild.config.ts` | plugin `copy-to-plugins-folder` ~l. 70-94 |
|
|
271
|
+
| Copie des templates vers le plugin cible | `scripts/inject-core.ts` | `injectScripts()` ~l. 455-612, `buildFileList()` ~l. 284-353 |
|
|
272
|
+
| Dépendance optionnelle | `esbuild-sass-plugin` (ajoutée par l'utilisateur si SCSS) | `README.md` § SASS Support, ~l. 85-96 |
|
|
273
|
+
| Ignore du fichier transitoire | `templates/gitignore.template` | `main.css` ligne 25-26 |
|
package/docs/audit.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Audit — obsidian-plugin-config
|
|
2
|
+
|
|
3
|
+
Audit mis à jour du repo d'injection de configuration pour plugins Obsidian.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Bugs & problèmes fonctionnels restants ou nouveaux
|
|
8
|
+
|
|
9
|
+
### 🔴 BUG — Erreurs de compilation TypeScript dans les templates & conflits d'IDE
|
|
10
|
+
|
|
11
|
+
Le fait d'avoir un fichier `package.json` et `tsconfig.json` directement sous `templates/` perturbe les IDE et cause des erreurs de types car `node_modules` n'y est plus présent.
|
|
12
|
+
De plus, la racine du projet (`tsconfig.json` de la racine) inclut `templates/**/*.ts` mais son `package.json` ne contient pas les dépendances de développement utilisées par les templates (`dotenv`, `builtin-modules`, `esbuild`, `obsidian`, `obsidian-typings`, `tslib`). Cela produit des erreurs `Cannot find module 'dotenv'` lors de l'exécution de `tsc` à la racine.
|
|
13
|
+
|
|
14
|
+
**Actions recommandées :**
|
|
15
|
+
1. Renommer `templates/package.json` en `templates/package.json.template`.
|
|
16
|
+
2. Renommer `templates/tsconfig.json` en `templates/tsconfig.json.template`.
|
|
17
|
+
3. Installer les dépendances requises par les templates en tant que `devDependencies` dans le `package.json` racine pour que le compilateur TS de la racine résolve correctement les types sans nécessiter de dossier `node_modules` dans `templates/`.
|
|
18
|
+
4. Mettre à jour le code d'injection dans [inject-core.ts](file:///c:/Users/dd200/Documents/Mes_projets/Mes%20repo%20obsidian%20new/obsidian-plugin-config/scripts/inject-core.ts) pour copier à partir des fichiers `.template` et les restaurer sans suffixe dans la cible.
|
|
19
|
+
5. Mettre à jour la documentation et les scripts d'aide pour mentionner les nouveaux noms de templates.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Incohérences & améliorations de code restantes
|
|
24
|
+
|
|
25
|
+
### 🟡 INCOHÉRENCE — Flags CLI inversés dans la doc
|
|
26
|
+
|
|
27
|
+
[INTERACTIVE_INJECTION.md:42-53](file:///c:/Users/dd200/Documents/Mes_projets/Mes%20repo%20obsidian%20new/obsidian-plugin-config/docs/INTERACTIVE_INJECTION.md#L42-L53)
|
|
28
|
+
|
|
29
|
+
Le tableau indique `--no, -n` pour la CLI globale comme « auto-confirme tous les remplacements ». C'est correct dans le code (`bin/obsidian-inject.js` L100 : `--no` / `-n`). Mais le nommage est contre-intuitif : `--no` signifie « pas de confirmation » (= auto-confirme tout), ce qui peut prêter à confusion car `--no` semble dire « non ».
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
### 🟡 Améliorations possibles (non-bloquantes)
|
|
34
|
+
|
|
35
|
+
| # | Suggestion | Impact |
|
|
36
|
+
|---|-----------|--------|
|
|
37
|
+
| 1 | Unifier les flags `--yes`/`--no` entre CLI globale et scripts locaux | UX |
|
|
38
|
+
| 2 | Remplacer le mix fs sync/async dans `inject-core.ts` par une approche uniforme | Propreté |
|
|
39
|
+
| 3 | Nettoyer les numéros de lignes obsolètes dans `docs/SCSS-FLOW.md` | Doc maintenance |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "obsidian-plugin-config",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"description": "Global CLI injection tool for Obsidian plugins",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,11 +34,17 @@
|
|
|
34
34
|
"@types/node": "^22.15.26",
|
|
35
35
|
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
|
36
36
|
"@typescript-eslint/parser": "^8.58.0",
|
|
37
|
+
"builtin-modules": "latest",
|
|
37
38
|
"dedent": "^1.6.0",
|
|
39
|
+
"dotenv": "latest",
|
|
40
|
+
"esbuild": "latest",
|
|
38
41
|
"eslint": "latest",
|
|
39
42
|
"eslint-import-resolver-typescript": "latest",
|
|
40
43
|
"jiti": "latest",
|
|
44
|
+
"obsidian": "*",
|
|
45
|
+
"obsidian-typings": "latest",
|
|
41
46
|
"prettier": "^3.4.0",
|
|
47
|
+
"tslib": "2.4.0",
|
|
42
48
|
"tsx": "^4.21.0",
|
|
43
49
|
"typescript": "^5.8.2"
|
|
44
50
|
},
|
package/scripts/acp.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
1
|
+
import { execSync, spawnSync } from 'child_process';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import {
|
|
@@ -39,7 +39,10 @@ async function main(): Promise<void> {
|
|
|
39
39
|
|
|
40
40
|
try {
|
|
41
41
|
gitExec('git add -A');
|
|
42
|
-
|
|
42
|
+
const result = spawnSync('git', ['commit', '-m', cleanedInput], { stdio: 'inherit' });
|
|
43
|
+
if (result.status !== 0) {
|
|
44
|
+
throw new Error('Commit failed');
|
|
45
|
+
}
|
|
43
46
|
} catch {
|
|
44
47
|
console.log('Commit already exists or failed.');
|
|
45
48
|
return;
|
package/scripts/help.ts
CHANGED
|
@@ -41,8 +41,8 @@ PURE INJECTION TOOL:
|
|
|
41
41
|
bin/obsidian-inject.js # Global CLI entry point
|
|
42
42
|
|
|
43
43
|
templates/ → what gets injected:
|
|
44
|
-
templates/package.json
|
|
45
|
-
templates/tsconfig.json
|
|
44
|
+
templates/package.json.template # Base deps/scripts for target plugins
|
|
45
|
+
templates/tsconfig.json.template # TypeScript config
|
|
46
46
|
templates/scripts/* # Scripts copied to target
|
|
47
47
|
templates/eslint.config.mts # ESLint config
|
|
48
48
|
templates/.github/workflows/* # GitHub Actions
|
package/scripts/inject-core.ts
CHANGED
|
@@ -106,11 +106,8 @@ export async function ensurePluginConfigClean(): Promise<void> {
|
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
const originalCwd = process.cwd();
|
|
110
|
-
|
|
111
109
|
try {
|
|
112
|
-
|
|
113
|
-
const gitStatus = execSync('git status --porcelain', { encoding: 'utf8' }).trim();
|
|
110
|
+
const gitStatus = execSync('git status --porcelain', { cwd: configRoot, encoding: 'utf8' }).trim();
|
|
114
111
|
|
|
115
112
|
if (gitStatus) {
|
|
116
113
|
console.log(`\n⚠️ Plugin-config has uncommitted changes:`);
|
|
@@ -118,21 +115,23 @@ export async function ensurePluginConfigClean(): Promise<void> {
|
|
|
118
115
|
console.log(`\n🔧 Auto-committing changes...`);
|
|
119
116
|
|
|
120
117
|
const msg = '🔧 Update plugin-config templates';
|
|
121
|
-
gitExec('git add -A');
|
|
122
|
-
gitExec(`git commit -m "${msg}"
|
|
118
|
+
gitExec('git add -A', configRoot);
|
|
119
|
+
gitExec(`git commit -m "${msg}"`, configRoot);
|
|
123
120
|
|
|
124
121
|
try {
|
|
125
122
|
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
123
|
+
cwd: configRoot,
|
|
126
124
|
encoding: 'utf8'
|
|
127
125
|
}).trim();
|
|
128
|
-
gitExec(`git push origin ${branch}
|
|
126
|
+
gitExec(`git push origin ${branch}`, configRoot);
|
|
129
127
|
console.log(`✅ Changes committed and pushed`);
|
|
130
128
|
} catch {
|
|
131
129
|
try {
|
|
132
130
|
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
131
|
+
cwd: configRoot,
|
|
133
132
|
encoding: 'utf8'
|
|
134
133
|
}).trim();
|
|
135
|
-
gitExec(`git push --set-upstream origin ${branch}
|
|
134
|
+
gitExec(`git push --set-upstream origin ${branch}`, configRoot);
|
|
136
135
|
console.log(`✅ New branch pushed with upstream`);
|
|
137
136
|
} catch {
|
|
138
137
|
console.log(`⚠️ Committed locally, push failed`);
|
|
@@ -141,8 +140,8 @@ export async function ensurePluginConfigClean(): Promise<void> {
|
|
|
141
140
|
} else {
|
|
142
141
|
console.log(`✅ Plugin-config repo is clean`);
|
|
143
142
|
}
|
|
144
|
-
}
|
|
145
|
-
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error(`⚠️ Failed to check or commit plugin-config: ${error}`);
|
|
146
145
|
}
|
|
147
146
|
}
|
|
148
147
|
|
|
@@ -255,8 +254,7 @@ export async function cleanOldLintFiles(targetPath: string): Promise<void> {
|
|
|
255
254
|
if (await isValidPath(filePath)) {
|
|
256
255
|
fs.unlinkSync(filePath);
|
|
257
256
|
console.log(
|
|
258
|
-
`🗑️ Removed old ESLint file: ${fileName} (replaced by
|
|
259
|
-
fig.ts)`
|
|
257
|
+
`🗑️ Removed old ESLint file: ${fileName} (replaced by eslint.config.mts)`
|
|
260
258
|
);
|
|
261
259
|
}
|
|
262
260
|
}
|
|
@@ -307,13 +305,14 @@ function buildFileList(targetPath: string): FileEntry[] {
|
|
|
307
305
|
|
|
308
306
|
// Root config files
|
|
309
307
|
const configFileMap: Array<[string, string, boolean?]> = [
|
|
310
|
-
['templates/tsconfig.json', 'tsconfig.json'],
|
|
308
|
+
['templates/tsconfig.json.template', 'tsconfig.json'],
|
|
311
309
|
['templates/gitignore.template', '.gitignore'],
|
|
312
310
|
['templates/eslint.config.mts', 'eslint.config.mts'],
|
|
313
311
|
['templates/.editorconfig', '.editorconfig'],
|
|
314
312
|
['templates/.prettierrc', '.prettierrc'],
|
|
315
313
|
['templates/.prettierignore', '.prettierignore'],
|
|
316
314
|
['templates/npmrc.template', '.npmrc'],
|
|
315
|
+
['templates/.gitattributes', '.gitattributes'],
|
|
317
316
|
['templates/env.template', '.env', true]
|
|
318
317
|
];
|
|
319
318
|
for (const [src, destName, mergeEnv] of configFileMap) {
|
|
@@ -486,13 +485,14 @@ export async function injectScripts(
|
|
|
486
485
|
// Files with .template suffix (NPM excludes dotfiles)
|
|
487
486
|
// Map: { source: targetName }
|
|
488
487
|
const configFileMap: Record<string, string> = {
|
|
489
|
-
'templates/tsconfig.json': 'tsconfig.json',
|
|
488
|
+
'templates/tsconfig.json.template': 'tsconfig.json',
|
|
490
489
|
'templates/gitignore.template': '.gitignore',
|
|
491
490
|
'templates/eslint.config.mts': 'eslint.config.mts',
|
|
492
491
|
'templates/.editorconfig': '.editorconfig',
|
|
493
492
|
'templates/.prettierrc': '.prettierrc',
|
|
494
493
|
'templates/.prettierignore': '.prettierignore',
|
|
495
494
|
'templates/npmrc.template': '.npmrc',
|
|
495
|
+
'templates/.gitattributes': '.gitattributes',
|
|
496
496
|
'templates/env.template': '.env'
|
|
497
497
|
};
|
|
498
498
|
|
|
@@ -629,7 +629,7 @@ export async function updatePackageJson(
|
|
|
629
629
|
|
|
630
630
|
const configRoot = findPluginConfigRoot();
|
|
631
631
|
const templatePkg = JSON.parse(
|
|
632
|
-
fs.readFileSync(path.join(configRoot, 'templates/package.json'), 'utf8')
|
|
632
|
+
fs.readFileSync(path.join(configRoot, 'templates/package.json.template'), 'utf8')
|
|
633
633
|
);
|
|
634
634
|
|
|
635
635
|
const obsoleteScripts = ['version'];
|
|
@@ -750,10 +750,11 @@ export async function cleanNpmArtifactsIfNeeded(targetPath: string): Promise<voi
|
|
|
750
750
|
if (fs.existsSync(nodeModulesPath)) {
|
|
751
751
|
console.log(` ⏳ Removing node_modules (this may take a moment)...`);
|
|
752
752
|
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
753
|
+
try {
|
|
754
|
+
fs.rmSync(nodeModulesPath, { recursive: true, force: true });
|
|
755
|
+
} catch {
|
|
756
|
+
// Ignore initial error, lock detection checks if it still exists below
|
|
757
|
+
}
|
|
757
758
|
|
|
758
759
|
if (fs.existsSync(nodeModulesPath)) {
|
|
759
760
|
// rmdir failed silently (locked .exe files) - rename instead
|
package/scripts/utils.ts
CHANGED
|
@@ -115,9 +115,9 @@ export async function copyFilesToTargetDir(buildPath: string): Promise<void> {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
export function gitExec(command: string): void {
|
|
118
|
+
export function gitExec(command: string, cwd?: string): void {
|
|
119
119
|
try {
|
|
120
|
-
execSync(command, { stdio: 'inherit' });
|
|
120
|
+
execSync(command, { stdio: 'inherit', ...(cwd ? { cwd } : {}) });
|
|
121
121
|
} catch (error: unknown) {
|
|
122
122
|
console.error(`Error executing '${command}':`, (error as Error).message);
|
|
123
123
|
throw error;
|
package/templates/scripts/acp.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
1
|
+
import { execSync, spawnSync } from 'child_process';
|
|
2
2
|
import {
|
|
3
3
|
askQuestion,
|
|
4
4
|
cleanInput,
|
|
@@ -23,7 +23,10 @@ async function main(): Promise<void> {
|
|
|
23
23
|
|
|
24
24
|
try {
|
|
25
25
|
gitExec('git add -A');
|
|
26
|
-
|
|
26
|
+
const result = spawnSync('git', ['commit', '-m', cleanedInput], { stdio: 'inherit' });
|
|
27
|
+
if (result.status !== 0) {
|
|
28
|
+
throw new Error('Commit failed');
|
|
29
|
+
}
|
|
27
30
|
} catch {
|
|
28
31
|
console.log('Commit already exists or failed.');
|
|
29
32
|
return;
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
copyFilesToTargetDir,
|
|
17
17
|
createReadlineInterface,
|
|
18
18
|
isValidPath,
|
|
19
|
-
|
|
19
|
+
renameMainCss
|
|
20
20
|
} from './utils.ts';
|
|
21
21
|
import { reloadObsidian } from './reload.ts';
|
|
22
22
|
|
|
@@ -56,11 +56,11 @@ async function createBuildContext(
|
|
|
56
56
|
}
|
|
57
57
|
})(),
|
|
58
58
|
{
|
|
59
|
-
name: '
|
|
59
|
+
name: 'rename-main-css',
|
|
60
60
|
setup(build: esbuild.PluginBuild): void {
|
|
61
61
|
build.onEnd(async (result) => {
|
|
62
62
|
if (result.errors.length === 0) {
|
|
63
|
-
await
|
|
63
|
+
await renameMainCss(buildPath);
|
|
64
64
|
}
|
|
65
65
|
});
|
|
66
66
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { access, mkdir, copyFile, rm, writeFile } from 'fs/promises';
|
|
1
|
+
import { access, mkdir, copyFile, rm, writeFile, rename } from 'fs/promises';
|
|
2
2
|
import { existsSync, readFileSync } from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import * as readline from 'readline';
|
|
@@ -122,9 +122,9 @@ export async function copyFilesToTargetDir(buildPath: string): Promise<void> {
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
export function gitExec(command: string): void {
|
|
125
|
+
export function gitExec(command: string, cwd?: string): void {
|
|
126
126
|
try {
|
|
127
|
-
execSync(command, { stdio: 'inherit' });
|
|
127
|
+
execSync(command, { stdio: 'inherit', ...(cwd ? { cwd } : {}) });
|
|
128
128
|
} catch (error: unknown) {
|
|
129
129
|
console.error(
|
|
130
130
|
`Error executing '${command}':`,
|
|
@@ -163,19 +163,20 @@ export async function ensureGitSync(): Promise<void> {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
|
-
*
|
|
167
|
-
* This
|
|
166
|
+
* Rename main.css file generated by esbuild when compiling SCSS to styles.css
|
|
167
|
+
* This ensures the compiled CSS is correctly recognized by Obsidian
|
|
168
168
|
*/
|
|
169
|
-
export async function
|
|
169
|
+
export async function renameMainCss(outdir: string): Promise<void> {
|
|
170
170
|
const mainCssPath = path.join(outdir, 'main.css');
|
|
171
|
+
const stylesCssPath = path.join(outdir, 'styles.css');
|
|
171
172
|
try {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
|
|
175
|
-
console.warn(
|
|
176
|
-
`Warning: Could not remove main.css: ${error instanceof Error ? error.message : String(error)}`
|
|
177
|
-
);
|
|
173
|
+
if (existsSync(mainCssPath)) {
|
|
174
|
+
await rename(mainCssPath, stylesCssPath);
|
|
178
175
|
}
|
|
176
|
+
} catch (error: unknown) {
|
|
177
|
+
console.warn(
|
|
178
|
+
`Warning: Could not rename main.css to styles.css: ${error instanceof Error ? error.message : String(error)}`
|
|
179
|
+
);
|
|
179
180
|
}
|
|
180
181
|
}
|
|
181
182
|
|
package/tsconfig.json
CHANGED
|
@@ -19,6 +19,6 @@
|
|
|
19
19
|
"resolveJsonModule": true,
|
|
20
20
|
"lib": ["DOM", "ES2024"]
|
|
21
21
|
},
|
|
22
|
-
"include": ["./scripts/**/*.ts"],
|
|
23
|
-
"exclude": ["node_modules", "eslint.config.ts"
|
|
22
|
+
"include": ["./scripts/**/*.ts", "templates/**/*.ts"],
|
|
23
|
+
"exclude": ["node_modules", "eslint.config.ts"]
|
|
24
24
|
}
|
|
File without changes
|