Skip to content

Commit 0fdd43b

Browse files
committed
Apply changesets and update CHANGELOG [skip ci]
1 parent 0ca4947 commit 0fdd43b

File tree

1 file changed

+148
-2
lines changed

1 file changed

+148
-2
lines changed

lib/README.md

Lines changed: 148 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ A Git-aware conflict resolver for **JSON-first structured data**.
2828
- 🔄 **Backup and restore** functionality
2929
- 📊 **Configurable logging** (memory or file-based)
3030
- 🔀 **Git merge driver** support for seamless Git integration
31+
- 🔧 **Plugin system** for custom strategies with JSON config support
3132

3233
## Installation
3334

@@ -114,7 +115,9 @@ await resolveConflicts({
114115
});
115116
```
116117

117-
### Config File (`git-json-resolver.config.js`)
118+
### Config File
119+
120+
**JavaScript Config (`git-json-resolver.config.js`)**
118121

119122
```js
120123
module.exports = {
@@ -151,6 +154,37 @@ module.exports = {
151154
};
152155
```
153156

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+
154188
## Supported Strategies
155189

156190
- **merge** → deep merge objects/arrays where possible
@@ -217,7 +251,115 @@ All non-JSON formats are converted to JSON → resolved → converted back to or
217251
- **Glob patterns**: `"dependencies.*"`, `"**.config.**"`
218252
- **Wildcards**: `"*.json"`, `"src/**/*.config.js"`
219253

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)
221363

222364
```ts
223365
import { StrategyStatus } from "git-json-resolver";
@@ -245,6 +387,10 @@ const config = {
245387
- **Per-file logs**: Separate log files for each processed file
246388
- **Debug mode**: Detailed conflict information and strategy traces
247389

390+
## Plugin Development
391+
392+
See [PLUGIN_GUIDE.md](./PLUGIN_GUIDE.md) for detailed plugin development documentation.
393+
248394
## Contributing
249395

250396
Contributions welcome 🙌

0 commit comments

Comments
 (0)