@tuicomponents/diff 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,400 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DiffComponent: () => DiffComponent,
24
+ createDiff: () => createDiff,
25
+ diffInputSchema: () => diffInputSchema,
26
+ diffLineSchema: () => diffLineSchema,
27
+ hunkSchema: () => hunkSchema,
28
+ lineTypeSchema: () => lineTypeSchema,
29
+ markerStyleSchema: () => markerStyleSchema
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/diff.ts
34
+ var import_core = require("@tuicomponents/core");
35
+ var import_zod_to_json_schema = require("zod-to-json-schema");
36
+
37
+ // src/schema.ts
38
+ var import_zod = require("zod");
39
+ var lineTypeSchema = import_zod.z.enum([
40
+ "addition",
41
+ // Added line (+)
42
+ "deletion",
43
+ // Removed line (-)
44
+ "context"
45
+ // Unchanged context line
46
+ ]);
47
+ var diffLineSchema = import_zod.z.object({
48
+ /**
49
+ * Type of the line.
50
+ */
51
+ type: lineTypeSchema,
52
+ /**
53
+ * Content of the line.
54
+ */
55
+ content: import_zod.z.string(),
56
+ /**
57
+ * Optional line number in the old file (for deletions and context).
58
+ */
59
+ oldLineNumber: import_zod.z.number().int().positive().optional(),
60
+ /**
61
+ * Optional line number in the new file (for additions and context).
62
+ */
63
+ newLineNumber: import_zod.z.number().int().positive().optional()
64
+ });
65
+ var hunkSchema = import_zod.z.object({
66
+ /**
67
+ * Hunk header information.
68
+ */
69
+ header: import_zod.z.object({
70
+ oldStart: import_zod.z.number().int().nonnegative(),
71
+ oldCount: import_zod.z.number().int().nonnegative(),
72
+ newStart: import_zod.z.number().int().nonnegative(),
73
+ newCount: import_zod.z.number().int().nonnegative()
74
+ }).optional(),
75
+ /**
76
+ * Lines in the hunk.
77
+ */
78
+ lines: import_zod.z.array(diffLineSchema)
79
+ });
80
+ var markerStyleSchema = import_zod.z.enum([
81
+ "symbol",
82
+ // +/- markers
83
+ "word",
84
+ // ADD/DEL markers
85
+ "none"
86
+ // No markers, rely on color/indentation
87
+ ]);
88
+ var diffInputSchema = import_zod.z.object({
89
+ /**
90
+ * Array of hunks containing diff lines.
91
+ */
92
+ hunks: import_zod.z.array(hunkSchema),
93
+ /**
94
+ * Optional old file name for header.
95
+ */
96
+ oldFile: import_zod.z.string().optional(),
97
+ /**
98
+ * Optional new file name for header.
99
+ */
100
+ newFile: import_zod.z.string().optional(),
101
+ /**
102
+ * Show line numbers.
103
+ * @default false
104
+ */
105
+ showLineNumbers: import_zod.z.boolean().default(false),
106
+ /**
107
+ * Style for line markers.
108
+ * @default "symbol"
109
+ */
110
+ markerStyle: markerStyleSchema.default("symbol"),
111
+ /**
112
+ * Show hunk headers (@@ -x,y +a,b @@).
113
+ * @default true
114
+ */
115
+ showHunkHeaders: import_zod.z.boolean().default(true),
116
+ /**
117
+ * Number of context lines to show around changes.
118
+ * This is informational only - the component renders what you provide.
119
+ */
120
+ contextLines: import_zod.z.number().int().nonnegative().optional()
121
+ });
122
+
123
+ // src/diff.ts
124
+ function getMarker(type, style) {
125
+ if (style === "none") {
126
+ return "";
127
+ }
128
+ if (style === "word") {
129
+ switch (type) {
130
+ case "addition":
131
+ return "ADD ";
132
+ case "deletion":
133
+ return "DEL ";
134
+ case "context":
135
+ return " ";
136
+ }
137
+ }
138
+ switch (type) {
139
+ case "addition":
140
+ return "+";
141
+ case "deletion":
142
+ return "-";
143
+ case "context":
144
+ return " ";
145
+ }
146
+ }
147
+ function formatLineNumbers(line, maxOldWidth, maxNewWidth) {
148
+ const oldNum = line.oldLineNumber !== void 0 ? String(line.oldLineNumber).padStart(maxOldWidth, " ") : " ".repeat(maxOldWidth);
149
+ const newNum = line.newLineNumber !== void 0 ? String(line.newLineNumber).padStart(maxNewWidth, " ") : " ".repeat(maxNewWidth);
150
+ return `${oldNum} ${newNum}`;
151
+ }
152
+ function colorLine(text, type, theme) {
153
+ if (!theme) {
154
+ return text;
155
+ }
156
+ switch (type) {
157
+ case "addition":
158
+ return theme.semantic.added(text);
159
+ case "deletion":
160
+ return theme.semantic.removed(text);
161
+ case "context":
162
+ return text;
163
+ }
164
+ }
165
+ function colorHeader(text, theme) {
166
+ if (!theme) {
167
+ return text;
168
+ }
169
+ return theme.semantic.secondary(text);
170
+ }
171
+ var DiffComponent = class extends import_core.BaseTuiComponent {
172
+ metadata = {
173
+ name: "diff",
174
+ description: "Renders unified diff format with additions and deletions",
175
+ version: "0.1.0",
176
+ examples: [
177
+ {
178
+ name: "basic",
179
+ description: "Simple diff with additions and deletions",
180
+ input: {
181
+ hunks: [
182
+ {
183
+ lines: [
184
+ { type: "context", content: "function greet() {" },
185
+ { type: "deletion", content: ' console.log("Hello");' },
186
+ {
187
+ type: "addition",
188
+ content: ' console.log("Hello, World!");'
189
+ },
190
+ { type: "context", content: "}" }
191
+ ]
192
+ }
193
+ ]
194
+ }
195
+ },
196
+ {
197
+ name: "with-file-headers",
198
+ description: "Diff with file name headers",
199
+ input: {
200
+ oldFile: "a/src/main.ts",
201
+ newFile: "b/src/main.ts",
202
+ hunks: [
203
+ {
204
+ header: { oldStart: 1, oldCount: 4, newStart: 1, newCount: 5 },
205
+ lines: [
206
+ { type: "context", content: "import { foo } from './foo';" },
207
+ { type: "addition", content: "import { bar } from './bar';" },
208
+ { type: "context", content: "" },
209
+ { type: "context", content: "export function main() {" },
210
+ { type: "deletion", content: " foo();" },
211
+ { type: "addition", content: " foo();" },
212
+ { type: "addition", content: " bar();" },
213
+ { type: "context", content: "}" }
214
+ ]
215
+ }
216
+ ]
217
+ }
218
+ },
219
+ {
220
+ name: "with-line-numbers",
221
+ description: "Diff with line numbers shown",
222
+ input: {
223
+ showLineNumbers: true,
224
+ hunks: [
225
+ {
226
+ lines: [
227
+ {
228
+ type: "context",
229
+ content: "const x = 1;",
230
+ oldLineNumber: 10,
231
+ newLineNumber: 10
232
+ },
233
+ {
234
+ type: "deletion",
235
+ content: "const y = 2;",
236
+ oldLineNumber: 11
237
+ },
238
+ {
239
+ type: "addition",
240
+ content: "const y = 3;",
241
+ newLineNumber: 11
242
+ },
243
+ {
244
+ type: "context",
245
+ content: "const z = x + y;",
246
+ oldLineNumber: 12,
247
+ newLineNumber: 12
248
+ }
249
+ ]
250
+ }
251
+ ]
252
+ }
253
+ },
254
+ {
255
+ name: "word-markers",
256
+ description: "Using word markers instead of symbols",
257
+ input: {
258
+ markerStyle: "word",
259
+ hunks: [
260
+ {
261
+ lines: [
262
+ { type: "context", content: "First line" },
263
+ { type: "deletion", content: "Old line" },
264
+ { type: "addition", content: "New line" },
265
+ { type: "context", content: "Last line" }
266
+ ]
267
+ }
268
+ ]
269
+ }
270
+ },
271
+ {
272
+ name: "multiple-hunks",
273
+ description: "Diff with multiple hunks",
274
+ input: {
275
+ oldFile: "config.json",
276
+ newFile: "config.json",
277
+ hunks: [
278
+ {
279
+ header: { oldStart: 2, oldCount: 3, newStart: 2, newCount: 3 },
280
+ lines: [
281
+ { type: "context", content: ' "name": "my-app",' },
282
+ { type: "deletion", content: ' "version": "1.0.0",' },
283
+ { type: "addition", content: ' "version": "1.1.0",' },
284
+ { type: "context", content: ' "description": "...",' }
285
+ ]
286
+ },
287
+ {
288
+ header: { oldStart: 10, oldCount: 2, newStart: 10, newCount: 3 },
289
+ lines: [
290
+ { type: "context", content: ' "dependencies": {' },
291
+ { type: "addition", content: ' "lodash": "^4.17.21",' },
292
+ { type: "context", content: ' "express": "^4.18.0"' }
293
+ ]
294
+ }
295
+ ]
296
+ }
297
+ }
298
+ ]
299
+ };
300
+ schema = diffInputSchema;
301
+ /**
302
+ * Override getJsonSchema to use direct schema generation.
303
+ */
304
+ getJsonSchema() {
305
+ return (0, import_zod_to_json_schema.zodToJsonSchema)(this.schema, {
306
+ name: this.metadata.name,
307
+ $refStrategy: "none"
308
+ });
309
+ }
310
+ render(input, context) {
311
+ const parsed = this.schema.parse(input);
312
+ const theme = context.theme;
313
+ if (parsed.hunks.length === 0) {
314
+ return { output: "", actualWidth: 0, lineCount: 0 };
315
+ }
316
+ const lines = [];
317
+ if (parsed.oldFile) {
318
+ lines.push(colorHeader(`--- ${parsed.oldFile}`, theme));
319
+ }
320
+ if (parsed.newFile) {
321
+ lines.push(colorHeader(`+++ ${parsed.newFile}`, theme));
322
+ }
323
+ const { maxOldWidth, maxNewWidth } = this.calculateLineNumberWidths(
324
+ parsed.hunks
325
+ );
326
+ for (const hunk of parsed.hunks) {
327
+ this.renderHunk(hunk, parsed, maxOldWidth, maxNewWidth, lines, theme);
328
+ }
329
+ const output = lines.join("\n");
330
+ const measured = (0, import_core.measureLines)(output);
331
+ return {
332
+ output,
333
+ actualWidth: measured.maxWidth,
334
+ lineCount: measured.lineCount
335
+ };
336
+ }
337
+ calculateLineNumberWidths(hunks) {
338
+ let maxOld = 0;
339
+ let maxNew = 0;
340
+ for (const hunk of hunks) {
341
+ for (const line of hunk.lines) {
342
+ if (line.oldLineNumber !== void 0 && line.oldLineNumber > maxOld) {
343
+ maxOld = line.oldLineNumber;
344
+ }
345
+ if (line.newLineNumber !== void 0 && line.newLineNumber > maxNew) {
346
+ maxNew = line.newLineNumber;
347
+ }
348
+ }
349
+ }
350
+ return {
351
+ maxOldWidth: Math.max(1, String(maxOld).length),
352
+ maxNewWidth: Math.max(1, String(maxNew).length)
353
+ };
354
+ }
355
+ renderHunk(hunk, config, maxOldWidth, maxNewWidth, lines, theme) {
356
+ if (config.showHunkHeaders && hunk.header) {
357
+ const { oldStart, oldCount, newStart, newCount } = hunk.header;
358
+ const header = `@@ -${String(oldStart)},${String(oldCount)} +${String(newStart)},${String(newCount)} @@`;
359
+ lines.push(colorHeader(header, theme));
360
+ }
361
+ for (const line of hunk.lines) {
362
+ const renderedLine = this.renderLine(
363
+ line,
364
+ config,
365
+ maxOldWidth,
366
+ maxNewWidth,
367
+ theme
368
+ );
369
+ lines.push(renderedLine);
370
+ }
371
+ }
372
+ renderLine(line, config, maxOldWidth, maxNewWidth, theme) {
373
+ const parts = [];
374
+ if (config.showLineNumbers) {
375
+ parts.push(formatLineNumbers(line, maxOldWidth, maxNewWidth));
376
+ }
377
+ const marker = getMarker(line.type, config.markerStyle);
378
+ if (marker) {
379
+ parts.push(marker);
380
+ }
381
+ parts.push(line.content);
382
+ const rawLine = config.showLineNumbers ? parts.join(" ") : parts.join("");
383
+ return colorLine(rawLine, line.type, theme);
384
+ }
385
+ };
386
+ function createDiff() {
387
+ return new DiffComponent();
388
+ }
389
+ import_core.registry.register(createDiff);
390
+ // Annotate the CommonJS export names for ESM import in node:
391
+ 0 && (module.exports = {
392
+ DiffComponent,
393
+ createDiff,
394
+ diffInputSchema,
395
+ diffLineSchema,
396
+ hunkSchema,
397
+ lineTypeSchema,
398
+ markerStyleSchema
399
+ });
400
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/diff.ts","../src/schema.ts"],"sourcesContent":["export { createDiff, DiffComponent } from \"./diff.js\";\nexport {\n diffInputSchema,\n diffLineSchema,\n hunkSchema,\n lineTypeSchema,\n markerStyleSchema,\n type DiffInput,\n type DiffInputWithDefaults,\n type DiffLine,\n type Hunk,\n type LineType,\n type MarkerStyle,\n} from \"./schema.js\";\n","import {\n BaseTuiComponent,\n type ComponentMetadata,\n type RenderContext,\n type RenderResult,\n type TuiTheme,\n measureLines,\n registry,\n} from \"@tuicomponents/core\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport {\n diffInputSchema,\n type DiffInput,\n type DiffInputWithDefaults,\n type DiffLine,\n type Hunk,\n type MarkerStyle,\n} from \"./schema.js\";\n\n/**\n * Get the marker for a line type.\n */\nfunction getMarker(type: DiffLine[\"type\"], style: MarkerStyle): string {\n if (style === \"none\") {\n return \"\";\n }\n\n if (style === \"word\") {\n switch (type) {\n case \"addition\":\n return \"ADD \";\n case \"deletion\":\n return \"DEL \";\n case \"context\":\n return \" \";\n }\n }\n\n // symbol style\n switch (type) {\n case \"addition\":\n return \"+\";\n case \"deletion\":\n return \"-\";\n case \"context\":\n return \" \";\n }\n}\n\n/**\n * Format line numbers for display.\n */\nfunction formatLineNumbers(\n line: DiffLine,\n maxOldWidth: number,\n maxNewWidth: number\n): string {\n const oldNum =\n line.oldLineNumber !== undefined\n ? String(line.oldLineNumber).padStart(maxOldWidth, \" \")\n : \" \".repeat(maxOldWidth);\n\n const newNum =\n line.newLineNumber !== undefined\n ? String(line.newLineNumber).padStart(maxNewWidth, \" \")\n : \" \".repeat(maxNewWidth);\n\n return `${oldNum} ${newNum}`;\n}\n\n/**\n * Apply color to a diff line based on its type.\n */\nfunction colorLine(\n text: string,\n type: DiffLine[\"type\"],\n theme: TuiTheme | undefined\n): string {\n if (!theme) {\n return text;\n }\n\n switch (type) {\n case \"addition\":\n return theme.semantic.added(text);\n case \"deletion\":\n return theme.semantic.removed(text);\n case \"context\":\n return text; // Context lines keep default color\n }\n}\n\n/**\n * Apply color to header text.\n */\nfunction colorHeader(text: string, theme: TuiTheme | undefined): string {\n if (!theme) {\n return text;\n }\n return theme.semantic.secondary(text);\n}\n\n/**\n * Diff component for rendering unified diff output.\n */\nclass DiffComponent extends BaseTuiComponent<\n DiffInput,\n typeof diffInputSchema\n> {\n readonly metadata: ComponentMetadata<DiffInput> = {\n name: \"diff\",\n description: \"Renders unified diff format with additions and deletions\",\n version: \"0.1.0\",\n examples: [\n {\n name: \"basic\",\n description: \"Simple diff with additions and deletions\",\n input: {\n hunks: [\n {\n lines: [\n { type: \"context\", content: \"function greet() {\" },\n { type: \"deletion\", content: ' console.log(\"Hello\");' },\n {\n type: \"addition\",\n content: ' console.log(\"Hello, World!\");',\n },\n { type: \"context\", content: \"}\" },\n ],\n },\n ],\n },\n },\n {\n name: \"with-file-headers\",\n description: \"Diff with file name headers\",\n input: {\n oldFile: \"a/src/main.ts\",\n newFile: \"b/src/main.ts\",\n hunks: [\n {\n header: { oldStart: 1, oldCount: 4, newStart: 1, newCount: 5 },\n lines: [\n { type: \"context\", content: \"import { foo } from './foo';\" },\n { type: \"addition\", content: \"import { bar } from './bar';\" },\n { type: \"context\", content: \"\" },\n { type: \"context\", content: \"export function main() {\" },\n { type: \"deletion\", content: \" foo();\" },\n { type: \"addition\", content: \" foo();\" },\n { type: \"addition\", content: \" bar();\" },\n { type: \"context\", content: \"}\" },\n ],\n },\n ],\n },\n },\n {\n name: \"with-line-numbers\",\n description: \"Diff with line numbers shown\",\n input: {\n showLineNumbers: true,\n hunks: [\n {\n lines: [\n {\n type: \"context\",\n content: \"const x = 1;\",\n oldLineNumber: 10,\n newLineNumber: 10,\n },\n {\n type: \"deletion\",\n content: \"const y = 2;\",\n oldLineNumber: 11,\n },\n {\n type: \"addition\",\n content: \"const y = 3;\",\n newLineNumber: 11,\n },\n {\n type: \"context\",\n content: \"const z = x + y;\",\n oldLineNumber: 12,\n newLineNumber: 12,\n },\n ],\n },\n ],\n },\n },\n {\n name: \"word-markers\",\n description: \"Using word markers instead of symbols\",\n input: {\n markerStyle: \"word\",\n hunks: [\n {\n lines: [\n { type: \"context\", content: \"First line\" },\n { type: \"deletion\", content: \"Old line\" },\n { type: \"addition\", content: \"New line\" },\n { type: \"context\", content: \"Last line\" },\n ],\n },\n ],\n },\n },\n {\n name: \"multiple-hunks\",\n description: \"Diff with multiple hunks\",\n input: {\n oldFile: \"config.json\",\n newFile: \"config.json\",\n hunks: [\n {\n header: { oldStart: 2, oldCount: 3, newStart: 2, newCount: 3 },\n lines: [\n { type: \"context\", content: ' \"name\": \"my-app\",' },\n { type: \"deletion\", content: ' \"version\": \"1.0.0\",' },\n { type: \"addition\", content: ' \"version\": \"1.1.0\",' },\n { type: \"context\", content: ' \"description\": \"...\",' },\n ],\n },\n {\n header: { oldStart: 10, oldCount: 2, newStart: 10, newCount: 3 },\n lines: [\n { type: \"context\", content: ' \"dependencies\": {' },\n { type: \"addition\", content: ' \"lodash\": \"^4.17.21\",' },\n { type: \"context\", content: ' \"express\": \"^4.18.0\"' },\n ],\n },\n ],\n },\n },\n ],\n };\n\n readonly schema = diffInputSchema;\n\n /**\n * Override getJsonSchema to use direct schema generation.\n */\n override getJsonSchema(): object {\n return zodToJsonSchema(this.schema, {\n name: this.metadata.name,\n $refStrategy: \"none\",\n });\n }\n\n render(input: DiffInput, context: RenderContext): RenderResult {\n const parsed: DiffInputWithDefaults = this.schema.parse(input);\n const theme = context.theme;\n\n if (parsed.hunks.length === 0) {\n return { output: \"\", actualWidth: 0, lineCount: 0 };\n }\n\n const lines: string[] = [];\n\n // Render file headers if provided (with muted color)\n if (parsed.oldFile) {\n lines.push(colorHeader(`--- ${parsed.oldFile}`, theme));\n }\n if (parsed.newFile) {\n lines.push(colorHeader(`+++ ${parsed.newFile}`, theme));\n }\n\n // Calculate max line number widths for padding\n const { maxOldWidth, maxNewWidth } = this.calculateLineNumberWidths(\n parsed.hunks\n );\n\n // Render each hunk\n for (const hunk of parsed.hunks) {\n this.renderHunk(hunk, parsed, maxOldWidth, maxNewWidth, lines, theme);\n }\n\n const output = lines.join(\"\\n\");\n const measured = measureLines(output);\n\n return {\n output,\n actualWidth: measured.maxWidth,\n lineCount: measured.lineCount,\n };\n }\n\n private calculateLineNumberWidths(hunks: Hunk[]): {\n maxOldWidth: number;\n maxNewWidth: number;\n } {\n let maxOld = 0;\n let maxNew = 0;\n\n for (const hunk of hunks) {\n for (const line of hunk.lines) {\n if (line.oldLineNumber !== undefined && line.oldLineNumber > maxOld) {\n maxOld = line.oldLineNumber;\n }\n if (line.newLineNumber !== undefined && line.newLineNumber > maxNew) {\n maxNew = line.newLineNumber;\n }\n }\n }\n\n return {\n maxOldWidth: Math.max(1, String(maxOld).length),\n maxNewWidth: Math.max(1, String(maxNew).length),\n };\n }\n\n private renderHunk(\n hunk: Hunk,\n config: DiffInputWithDefaults,\n maxOldWidth: number,\n maxNewWidth: number,\n lines: string[],\n theme: TuiTheme | undefined\n ): void {\n // Render hunk header if enabled and header data provided (with muted color)\n if (config.showHunkHeaders && hunk.header) {\n const { oldStart, oldCount, newStart, newCount } = hunk.header;\n const header = `@@ -${String(oldStart)},${String(oldCount)} +${String(newStart)},${String(newCount)} @@`;\n lines.push(colorHeader(header, theme));\n }\n\n // Render each line\n for (const line of hunk.lines) {\n const renderedLine = this.renderLine(\n line,\n config,\n maxOldWidth,\n maxNewWidth,\n theme\n );\n lines.push(renderedLine);\n }\n }\n\n private renderLine(\n line: DiffLine,\n config: DiffInputWithDefaults,\n maxOldWidth: number,\n maxNewWidth: number,\n theme: TuiTheme | undefined\n ): string {\n const parts: string[] = [];\n\n // Add line numbers if enabled\n if (config.showLineNumbers) {\n parts.push(formatLineNumbers(line, maxOldWidth, maxNewWidth));\n }\n\n // Add marker\n const marker = getMarker(line.type, config.markerStyle);\n if (marker) {\n parts.push(marker);\n }\n\n // Add content\n parts.push(line.content);\n\n // Join with appropriate separators\n const rawLine = config.showLineNumbers ? parts.join(\" \") : parts.join(\"\");\n\n // Apply color based on line type\n return colorLine(rawLine, line.type, theme);\n }\n}\n\n/**\n * Factory function to create a diff component.\n */\nexport function createDiff(): DiffComponent {\n return new DiffComponent();\n}\n\n// Register with global registry\nregistry.register(createDiff);\n\nexport { DiffComponent };\n","import { z } from \"zod\";\n\n/**\n * Type of diff line.\n */\nexport const lineTypeSchema = z.enum([\n \"addition\", // Added line (+)\n \"deletion\", // Removed line (-)\n \"context\", // Unchanged context line\n]);\n\nexport type LineType = z.infer<typeof lineTypeSchema>;\n\n/**\n * Schema for a single diff line.\n */\nexport const diffLineSchema = z.object({\n /**\n * Type of the line.\n */\n type: lineTypeSchema,\n\n /**\n * Content of the line.\n */\n content: z.string(),\n\n /**\n * Optional line number in the old file (for deletions and context).\n */\n oldLineNumber: z.number().int().positive().optional(),\n\n /**\n * Optional line number in the new file (for additions and context).\n */\n newLineNumber: z.number().int().positive().optional(),\n});\n\nexport type DiffLine = z.infer<typeof diffLineSchema>;\n\n/**\n * Schema for a hunk (section of changes).\n */\nexport const hunkSchema = z.object({\n /**\n * Hunk header information.\n */\n header: z\n .object({\n oldStart: z.number().int().nonnegative(),\n oldCount: z.number().int().nonnegative(),\n newStart: z.number().int().nonnegative(),\n newCount: z.number().int().nonnegative(),\n })\n .optional(),\n\n /**\n * Lines in the hunk.\n */\n lines: z.array(diffLineSchema),\n});\n\nexport type Hunk = z.infer<typeof hunkSchema>;\n\n/**\n * Style options for line markers.\n */\nexport const markerStyleSchema = z.enum([\n \"symbol\", // +/- markers\n \"word\", // ADD/DEL markers\n \"none\", // No markers, rely on color/indentation\n]);\n\nexport type MarkerStyle = z.infer<typeof markerStyleSchema>;\n\n/**\n * Schema for diff component input.\n */\nexport const diffInputSchema = z.object({\n /**\n * Array of hunks containing diff lines.\n */\n hunks: z.array(hunkSchema),\n\n /**\n * Optional old file name for header.\n */\n oldFile: z.string().optional(),\n\n /**\n * Optional new file name for header.\n */\n newFile: z.string().optional(),\n\n /**\n * Show line numbers.\n * @default false\n */\n showLineNumbers: z.boolean().default(false),\n\n /**\n * Style for line markers.\n * @default \"symbol\"\n */\n markerStyle: markerStyleSchema.default(\"symbol\"),\n\n /**\n * Show hunk headers (@@ -x,y +a,b @@).\n * @default true\n */\n showHunkHeaders: z.boolean().default(true),\n\n /**\n * Number of context lines to show around changes.\n * This is informational only - the component renders what you provide.\n */\n contextLines: z.number().int().nonnegative().optional(),\n});\n\nexport type DiffInput = z.input<typeof diffInputSchema>;\nexport type DiffInputWithDefaults = z.output<typeof diffInputSchema>;\n"],"mappings":"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","names":[]}