Skip to content

Commit 1959ebc

Browse files
authored
Merge pull request #6 from md2docx/merge-options-utils
Merge options utils
2 parents 0d571e6 + a205963 commit 1959ebc

File tree

8 files changed

+105
-5
lines changed

8 files changed

+105
-5
lines changed

lib/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# @m2d/core
22

3+
## 1.4.3
4+
5+
### Patch Changes
6+
7+
- 26199b2: Attempt to keep entire code block on same page.
8+
- 4fbac23: feat/utils: add mergeOptions function for deep merging user and default options
9+
310
## 1.4.2
411

512
### Patch Changes

lib/__tests__/index.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ describe("toDocx", () => {
3232
const docxBlob = await toDocx(
3333
mdast,
3434
{ title: "Custom Title" },
35-
// @ts-expect-error WIP
3635
{ plugins: [htmlPlugin(), listPlugin()] },
3736
);
3837

lib/__tests__/utils.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { describe, it } from "vitest";
2+
import { mergeOptions } from "../src/utils";
3+
4+
describe.concurrent("mergeOptions", () => {
5+
it("should return defaultOptions if options is undefined", ({ expect }) => {
6+
const defaults = { a: 1, b: 2 };
7+
const result = mergeOptions(undefined, defaults);
8+
expect(result).toEqual(defaults);
9+
});
10+
11+
it("should return options if defaultOptions is undefined", ({ expect }) => {
12+
const opts = { a: 3, b: 4 };
13+
const result = mergeOptions(opts, undefined);
14+
expect(result).toEqual(opts);
15+
});
16+
17+
it("should deeply merge nested objects", ({ expect }) => {
18+
const defaults = { a: 1, b: { c: 2, d: 3 } };
19+
const opts = { b: { c: 5 } };
20+
const result = mergeOptions(opts, defaults);
21+
expect(result).toEqual({ a: 1, b: { c: 5, d: 3 } });
22+
});
23+
24+
it("should override primitive values", ({ expect }) => {
25+
const defaults = { a: 1, b: 2 };
26+
const opts = { b: 5 };
27+
const result = mergeOptions(opts, defaults);
28+
expect(result).toEqual({ a: 1, b: 5 });
29+
});
30+
31+
it("should not merge arrays, but override them", ({ expect }) => {
32+
const defaults = { arr: [1, 2, 3], b: 2 };
33+
const opts = { arr: [4, 5] };
34+
const result = mergeOptions(opts, defaults);
35+
expect(result).toEqual({ arr: [4, 5], b: 2 });
36+
});
37+
38+
it("should handle null and undefined values in options", ({ expect }) => {
39+
const defaults = { a: 1, b: 2 };
40+
const opts = { a: null, b: undefined };
41+
const result = mergeOptions(opts, defaults as any);
42+
expect(result).toEqual({ a: null, b: undefined });
43+
});
44+
45+
it("should handle both options and defaultOptions as undefined", ({ expect }) => {
46+
const result = mergeOptions(undefined, undefined);
47+
expect(result).toEqual({});
48+
});
49+
50+
it("should not mutate the input objects", ({ expect }) => {
51+
const defaults = { a: 1, b: { c: 2 } };
52+
const opts = { b: { d: 3 } };
53+
const defaultsCopy = JSON.parse(JSON.stringify(defaults));
54+
const optsCopy = JSON.parse(JSON.stringify(opts));
55+
mergeOptions(opts, defaults as any);
56+
expect(defaults).toEqual(defaultsCopy);
57+
expect(opts).toEqual(optsCopy);
58+
});
59+
});

lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@m2d/core",
33
"author": "Mayank Kumar Chaudhari (https://mayank-chaudhari.vercel.app)",
44
"private": false,
5-
"version": "1.4.2",
5+
"version": "1.4.3",
66
"description": "Core engine to convert extended MDAST to DOCX. Supports plugins for footnotes, images, lists, tables, and more. Designed for seamless Markdown-to-DOCX conversion.",
77
"license": "MPL-2.0",
88
"main": "./dist/index.js",

lib/src/section.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ export const toSection = async (
237237
...newParaProps,
238238
alignment: "left",
239239
style: "blockCode",
240+
keepLines: true,
240241
children: node.value.split("\n").map(
241242
(line, i) =>
242243
// @ts-expect-error -- ok to pass extra data

lib/src/utils/index.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,32 @@ export interface IPlugin<T extends Node = EmptyNode> {
222222
}
223223

224224
/**
225-
* @mayank/docx is a fork of the `docx` library with minor modifications,
226-
* primarily adding exports for additional types missing from the original `docx` library.
225+
* Deeply merges user options over default options.
226+
* Later values override earlier ones. Arrays are not merged.
227+
*
228+
* @param options - User-provided overrides.
229+
* @param defaultOptions - Default values.
230+
* @returns A deeply merged object.
227231
*/
232+
export function mergeOptions<T>(options?: Partial<T>, defaultOptions?: Partial<T>): T {
233+
const result: any = { ...defaultOptions, ...options };
234+
235+
if (options) {
236+
for (const [key, value] of Object.entries(options)) {
237+
const defaultVal = (defaultOptions as any)?.[key];
238+
239+
if (
240+
value &&
241+
typeof value === "object" &&
242+
!Array.isArray(value) &&
243+
defaultVal &&
244+
typeof defaultVal === "object" &&
245+
!Array.isArray(defaultVal)
246+
) {
247+
result[key] = mergeOptions(value, defaultVal);
248+
}
249+
}
250+
}
251+
252+
return result as T;
253+
}

packages/shared/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# @repo/shared
22

3+
## 0.0.24
4+
5+
### Patch Changes
6+
7+
- Updated dependencies [26199b2]
8+
- Updated dependencies [4fbac23]
9+
- @m2d/core@1.4.3
10+
311
## 0.0.23
412

513
### Patch Changes

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@repo/shared",
3-
"version": "0.0.23",
3+
"version": "0.0.24",
44
"private": true,
55
"sideEffects": false,
66
"main": "./dist/index.js",

0 commit comments

Comments
 (0)