@@ -28,6 +28,7 @@ A Git-aware conflict resolver for **JSON-first structured data**.
28
28
- 🔄 ** Backup and restore** functionality
29
29
- 📊 ** Configurable logging** (memory or file-based)
30
30
- 🔀 ** Git merge driver** support for seamless Git integration
31
+ - 🔧 ** Plugin system** for custom strategies with JSON config support
31
32
32
33
## Installation
33
34
@@ -114,7 +115,9 @@ await resolveConflicts({
114
115
});
115
116
```
116
117
117
- ### Config File (` git-json-resolver.config.js ` )
118
+ ### Config File
119
+
120
+ ** JavaScript Config (` git-json-resolver.config.js ` )**
118
121
119
122
``` js
120
123
module .exports = {
@@ -151,6 +154,37 @@ module.exports = {
151
154
};
152
155
```
153
156
157
+ ** JSON Config (` git-json-resolver.config.json ` ) - ⚠️ Experimental**
158
+
159
+ ``` json
160
+ {
161
+ "$schema" : " https://cdn.jsdelivr.net/npm/git-json-resolver@latest/schema/config.schema.json" ,
162
+ "defaultStrategy" : [" merge" , " ours" ],
163
+ "plugins" : [" my-plugin" ],
164
+ "pluginConfig" : {
165
+ "my-plugin" : {
166
+ "option" : " value"
167
+ }
168
+ },
169
+ "rules" : {
170
+ "package.json" : {
171
+ "version" : [" semantic-version" , " theirs" ],
172
+ "dependencies" : [" ours" ]
173
+ }
174
+ },
175
+ "byStrategy" : {
176
+ "ours" : [" dependencies.*" , " devDependencies.*" ],
177
+ "theirs!" : [" version" , " name" ]
178
+ }
179
+ }
180
+ ```
181
+
182
+ ** ⚠️ JSON Config Limitations:**
183
+ - No TypeScript intellisense for plugin strategies
184
+ - Limited validation for custom strategy names
185
+ - No compile-time type checking
186
+ - ** Recommended:** Use ` .js ` or ` .ts ` config for better developer experience
187
+
154
188
## Supported Strategies
155
189
156
190
- ** merge** → deep merge objects/arrays where possible
@@ -217,7 +251,115 @@ All non-JSON formats are converted to JSON → resolved → converted back to or
217
251
- ** Glob patterns** : ` "dependencies.*" ` , ` "**.config.**" `
218
252
- ** Wildcards** : ` "*.json" ` , ` "src/**/*.config.js" `
219
253
220
- ### Custom Strategies
254
+ ### Plugin System
255
+
256
+ ** For TypeScript/JavaScript configs, you can use either approach:**
257
+
258
+ #### 1. Direct Import (Recommended)
259
+
260
+ ``` ts
261
+ import { strategies } from " my-plugin" ;
262
+ // or import { semanticVersion, timestampLatest } from "my-plugin";
263
+ import { resolveConflicts } from " git-json-resolver" ;
264
+
265
+ await resolveConflicts ({
266
+ customStrategies: {
267
+ ... strategies ,
268
+ // or "semantic-version": semanticVersion,
269
+ },
270
+ rules: {
271
+ version: [" semantic-version" , " theirs" ]
272
+ }
273
+ });
274
+ ```
275
+
276
+ #### 2. Dynamic Loading
277
+
278
+ ``` ts
279
+ // Also works in .js/.ts configs
280
+ const config = {
281
+ plugins: [" my-plugin" ],
282
+ pluginConfig: {
283
+ " my-plugin" : { option: " value" }
284
+ },
285
+ rules: {
286
+ version: [" semantic-version" , " theirs" ]
287
+ }
288
+ };
289
+ ```
290
+
291
+ #### 3. JSON Config (Dynamic Loading Only)
292
+
293
+ ``` json
294
+ {
295
+ "plugins" : [" my-plugin" ],
296
+ "pluginConfig" : {
297
+ "my-plugin" : { "option" : " value" }
298
+ },
299
+ "rules" : {
300
+ "version" : [" semantic-version" , " theirs" ]
301
+ }
302
+ }
303
+ ```
304
+
305
+ ** ⚠️ If plugin doesn't provide global types:**
306
+
307
+ ``` ts
308
+ import type { Config } from " git-json-resolver" ;
309
+
310
+ const config: Config <AllStrategies | " semantic-version" | " timestamp-latest" > = {
311
+ // ... your config
312
+ };
313
+ ```
314
+
315
+ ** Creating a Plugin**
316
+
317
+ ``` ts
318
+ import { StrategyPlugin , StrategyStatus , StrategyFn } from " git-json-resolver" ;
319
+
320
+ // Augment types for TypeScript support
321
+ declare module " git-json-resolver" {
322
+ interface PluginStrategies {
323
+ " semantic-version" : string ;
324
+ " timestamp-latest" : string ;
325
+ }
326
+ }
327
+
328
+ // Individual strategy functions (can be imported directly)
329
+ export const semanticVersion: StrategyFn = ({ ours , theirs }) => {
330
+ if (isNewerVersion (theirs , ours )) {
331
+ return { status: StrategyStatus .OK , value: theirs };
332
+ }
333
+ return { status: StrategyStatus .CONTINUE };
334
+ };
335
+
336
+ export const timestampLatest: StrategyFn = ({ ours , theirs }) => {
337
+ const oursTime = new Date (ours as string ).getTime ();
338
+ const theirsTime = new Date (theirs as string ).getTime ();
339
+ return {
340
+ status: StrategyStatus .OK ,
341
+ value: oursTime > theirsTime ? ours : theirs
342
+ };
343
+ };
344
+
345
+ // Export strategies object for direct import
346
+ export const strategies = {
347
+ " semantic-version" : semanticVersion ,
348
+ " timestamp-latest" : timestampLatest ,
349
+ };
350
+
351
+ // Plugin interface for dynamic loading
352
+ const plugin: StrategyPlugin = {
353
+ strategies ,
354
+ init : async (config ) => {
355
+ console .log (' Plugin initialized with:' , config );
356
+ }
357
+ };
358
+
359
+ export default plugin ;
360
+ ```
361
+
362
+ ### Custom Strategies (Inline)
221
363
222
364
``` ts
223
365
import { StrategyStatus } from " git-json-resolver" ;
@@ -245,6 +387,10 @@ const config = {
245
387
- ** Per-file logs** : Separate log files for each processed file
246
388
- ** Debug mode** : Detailed conflict information and strategy traces
247
389
390
+ ## Plugin Development
391
+
392
+ See [ PLUGIN_GUIDE.md] ( ./PLUGIN_GUIDE.md ) for detailed plugin development documentation.
393
+
248
394
## Contributing
249
395
250
396
Contributions welcome 🙌
0 commit comments