hwp-convert 1.0.0
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/CHANGELOG.md +185 -0
- package/LICENSE +25 -0
- package/NOTICE +23 -0
- package/README.md +338 -0
- package/dist/browser/hwp-convert.browser.mjs +20677 -0
- package/dist/browser/hwp-convert.browser.mjs.map +7 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +267 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/lib/errors.d.ts +9 -0
- package/dist/lib/errors.js +18 -0
- package/dist/lib/hwp/binData.d.ts +15 -0
- package/dist/lib/hwp/binData.js +64 -0
- package/dist/lib/hwp/bodyText.d.ts +31 -0
- package/dist/lib/hwp/bodyText.js +208 -0
- package/dist/lib/hwp/byteReader.d.ts +40 -0
- package/dist/lib/hwp/byteReader.js +116 -0
- package/dist/lib/hwp/cfbReader.d.ts +44 -0
- package/dist/lib/hwp/cfbReader.js +134 -0
- package/dist/lib/hwp/control.d.ts +17 -0
- package/dist/lib/hwp/control.js +290 -0
- package/dist/lib/hwp/converter.d.ts +22 -0
- package/dist/lib/hwp/converter.js +41 -0
- package/dist/lib/hwp/docInfo.d.ts +26 -0
- package/dist/lib/hwp/docInfo.js +396 -0
- package/dist/lib/hwp/fileHeader.d.ts +42 -0
- package/dist/lib/hwp/fileHeader.js +66 -0
- package/dist/lib/hwp/htmlReader.d.ts +17 -0
- package/dist/lib/hwp/htmlReader.js +602 -0
- package/dist/lib/hwp/hwpxBuilder.d.ts +19 -0
- package/dist/lib/hwp/hwpxBuilder.js +633 -0
- package/dist/lib/hwp/index.d.ts +68 -0
- package/dist/lib/hwp/index.js +149 -0
- package/dist/lib/hwp/mdReader.d.ts +16 -0
- package/dist/lib/hwp/mdReader.js +485 -0
- package/dist/lib/hwp/mdWriter.d.ts +23 -0
- package/dist/lib/hwp/mdWriter.js +182 -0
- package/dist/lib/hwp/owpml.d.ts +33 -0
- package/dist/lib/hwp/owpml.js +86 -0
- package/dist/lib/hwp/record.d.ts +24 -0
- package/dist/lib/hwp/record.js +59 -0
- package/dist/lib/hwp/tags.d.ts +115 -0
- package/dist/lib/hwp/tags.js +217 -0
- package/dist/lib/hwp/types.d.ts +214 -0
- package/dist/lib/hwp/types.js +5 -0
- package/dist/lib/hwpxReader.d.ts +60 -0
- package/dist/lib/hwpxReader.js +1104 -0
- package/dist/lib/types.d.ts +47 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/writer.d.ts +19 -0
- package/dist/lib/writer.js +149 -0
- package/package.json +94 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export interface HwpxMetadata {
|
|
2
|
+
title?: string;
|
|
3
|
+
creator?: string;
|
|
4
|
+
created?: string;
|
|
5
|
+
modified?: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
caretPosition?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface HwpxTextExtractOptions {
|
|
10
|
+
joinParagraphs?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface HwpxHtmlOptions {
|
|
13
|
+
paragraphTag?: string;
|
|
14
|
+
tableClassName?: string;
|
|
15
|
+
imageSrcResolver?: (binPath: string) => string;
|
|
16
|
+
renderImages?: boolean;
|
|
17
|
+
renderTables?: boolean;
|
|
18
|
+
renderStyles?: boolean;
|
|
19
|
+
embedImages?: boolean;
|
|
20
|
+
tableHeaderFirstRow?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export type TemplateData = Record<string, unknown>;
|
|
23
|
+
export interface HwpxFileMap {
|
|
24
|
+
[path: string]: Uint8Array;
|
|
25
|
+
}
|
|
26
|
+
export interface HwpxManifestItem {
|
|
27
|
+
id?: string;
|
|
28
|
+
href?: string;
|
|
29
|
+
mediaType?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface HwpxPackageSummary {
|
|
32
|
+
hasEncryptionInfo: boolean;
|
|
33
|
+
contentsFiles: string[];
|
|
34
|
+
manifest?: HwpxManifestItem[];
|
|
35
|
+
spine?: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface HwpxDocumentInfo {
|
|
38
|
+
metadata: HwpxMetadata;
|
|
39
|
+
summary: HwpxPackageSummary;
|
|
40
|
+
}
|
|
41
|
+
export interface HwpxReaderApi {
|
|
42
|
+
loadFromArrayBuffer(buffer: ArrayBuffer): Promise<void>;
|
|
43
|
+
getDocumentInfo(): Promise<HwpxDocumentInfo>;
|
|
44
|
+
extractText(options?: HwpxTextExtractOptions): Promise<string>;
|
|
45
|
+
extractHtml(options?: HwpxHtmlOptions): Promise<string>;
|
|
46
|
+
listImages(): Promise<string[]>;
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface HwpxWriteOptions {
|
|
2
|
+
title?: string;
|
|
3
|
+
creator?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* HWPX(OWPML) 패키지 빌더 (평문 → HWPX).
|
|
7
|
+
*
|
|
8
|
+
* OWPML 패키지 규칙(한컴 호환):
|
|
9
|
+
* - mimetype 엔트리는 ZIP 내 첫 번째이며 STORE(무압축), 내용은 "application/hwp+zip".
|
|
10
|
+
* - 요소만 네임스페이스 prefix(hp:/hh:), 속성은 prefix 없음.
|
|
11
|
+
* - head/sec/package 루트에 풀 네임스페이스 선언, 첫 문단에 <hp:secPr>.
|
|
12
|
+
* - META-INF/container.xml 가 rootfile 위치를 가리킴.
|
|
13
|
+
* - 공통 컨벤션 상수는 ./hwp/owpml.ts 와 공유.
|
|
14
|
+
* [shyang 2026-06-21]
|
|
15
|
+
*/
|
|
16
|
+
export declare class HwpxWriter {
|
|
17
|
+
createFromPlainText(text: string, options?: HwpxWriteOptions): Promise<Uint8Array>;
|
|
18
|
+
}
|
|
19
|
+
export default HwpxWriter;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import JSZip from "jszip";
|
|
2
|
+
import { MIMETYPE, OWPML_NS, DEFAULT_LINESEG, SEC_PR_XML, makeParaId, escapeXml, } from "./hwp/owpml.js";
|
|
3
|
+
const NS_HA = "http://www.hancom.co.kr/hwpml/2011/app";
|
|
4
|
+
const NS_OASIS_CONTAINER = "urn:oasis:names:tc:opendocument:xmlns:container";
|
|
5
|
+
const NS_OASIS_MANIFEST = "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0";
|
|
6
|
+
/**
|
|
7
|
+
* HWPX(OWPML) 패키지 빌더 (평문 → HWPX).
|
|
8
|
+
*
|
|
9
|
+
* OWPML 패키지 규칙(한컴 호환):
|
|
10
|
+
* - mimetype 엔트리는 ZIP 내 첫 번째이며 STORE(무압축), 내용은 "application/hwp+zip".
|
|
11
|
+
* - 요소만 네임스페이스 prefix(hp:/hh:), 속성은 prefix 없음.
|
|
12
|
+
* - head/sec/package 루트에 풀 네임스페이스 선언, 첫 문단에 <hp:secPr>.
|
|
13
|
+
* - META-INF/container.xml 가 rootfile 위치를 가리킴.
|
|
14
|
+
* - 공통 컨벤션 상수는 ./hwp/owpml.ts 와 공유.
|
|
15
|
+
* [shyang 2026-06-21]
|
|
16
|
+
*/
|
|
17
|
+
export class HwpxWriter {
|
|
18
|
+
async createFromPlainText(text, options) {
|
|
19
|
+
const zip = new JSZip();
|
|
20
|
+
// mimetype: 반드시 첫 엔트리, STORED.
|
|
21
|
+
zip.file("mimetype", MIMETYPE, { compression: "STORE" });
|
|
22
|
+
// META-INF/container.xml — rootfile 위치
|
|
23
|
+
const containerXml = `<?xml version="1.0" encoding="UTF-8"?>\n` +
|
|
24
|
+
`<container xmlns="${NS_OASIS_CONTAINER}">` +
|
|
25
|
+
`<rootfiles>` +
|
|
26
|
+
`<rootfile full-path="Contents/content.hpf" media-type="application/hwpml-package+xml"/>` +
|
|
27
|
+
`</rootfiles>` +
|
|
28
|
+
`</container>`;
|
|
29
|
+
zip.file("META-INF/container.xml", containerXml);
|
|
30
|
+
// META-INF/manifest.xml — 패키지 매니페스트
|
|
31
|
+
const manifestXml = `<?xml version="1.0" encoding="UTF-8"?>\n` +
|
|
32
|
+
`<manifest:manifest xmlns:manifest="${NS_OASIS_MANIFEST}">` +
|
|
33
|
+
`<manifest:file-entry manifest:full-path="/" manifest:media-type="application/hwpml-package+xml"/>` +
|
|
34
|
+
`<manifest:file-entry manifest:full-path="version.xml" manifest:media-type="application/xml"/>` +
|
|
35
|
+
`<manifest:file-entry manifest:full-path="settings.xml" manifest:media-type="application/xml"/>` +
|
|
36
|
+
`<manifest:file-entry manifest:full-path="Contents/content.hpf" manifest:media-type="application/hwpml-package+xml"/>` +
|
|
37
|
+
`<manifest:file-entry manifest:full-path="Contents/header.xml" manifest:media-type="application/xml"/>` +
|
|
38
|
+
`<manifest:file-entry manifest:full-path="Contents/section0.xml" manifest:media-type="application/xml"/>` +
|
|
39
|
+
`</manifest:manifest>`;
|
|
40
|
+
zip.file("META-INF/manifest.xml", manifestXml);
|
|
41
|
+
// version.xml
|
|
42
|
+
const version = `<?xml version="1.0" encoding="UTF-8"?>\n` +
|
|
43
|
+
`<ha:HCFVersion xmlns:ha="${NS_HA}" ha:targetApplication="WORDPROCESSOR" ha:major="5" ha:minor="0" ha:micro="6" ha:buildNumber="0"/>`;
|
|
44
|
+
zip.file("version.xml", version);
|
|
45
|
+
// settings.xml
|
|
46
|
+
const settings = `<?xml version="1.0" encoding="UTF-8"?>\n` +
|
|
47
|
+
`<ha:HWPApplicationSetting xmlns:ha="${NS_HA}">` +
|
|
48
|
+
`<ha:CaretPosition ha:listIDRef="0" ha:paraIDRef="0" ha:pos="0"/>` +
|
|
49
|
+
`</ha:HWPApplicationSetting>`;
|
|
50
|
+
zip.file("settings.xml", settings);
|
|
51
|
+
// Contents/content.hpf (OPF-like) — spine 에 header 포함
|
|
52
|
+
const contentHpf = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
|
|
53
|
+
`<opf:package ${OWPML_NS} version="" unique-identifier="" id="">` +
|
|
54
|
+
`<opf:metadata>` +
|
|
55
|
+
`<dc:title>${escapeXml(options?.title ?? "")}</dc:title>` +
|
|
56
|
+
`<dc:creator>${escapeXml(options?.creator ?? "")}</dc:creator>` +
|
|
57
|
+
`<dc:format>application/hwpml-package+xml</dc:format>` +
|
|
58
|
+
`</opf:metadata>` +
|
|
59
|
+
`<opf:manifest>` +
|
|
60
|
+
`<opf:item id="header" href="Contents/header.xml" media-type="application/xml"/>` +
|
|
61
|
+
`<opf:item id="section0" href="Contents/section0.xml" media-type="application/xml"/>` +
|
|
62
|
+
`<opf:item id="settings" href="settings.xml" media-type="application/xml"/>` +
|
|
63
|
+
`</opf:manifest>` +
|
|
64
|
+
`<opf:spine>` +
|
|
65
|
+
`<opf:itemref idref="header" linear="yes"/>` +
|
|
66
|
+
`<opf:itemref idref="section0" linear="yes"/>` +
|
|
67
|
+
`</opf:spine>` +
|
|
68
|
+
`</opf:package>`;
|
|
69
|
+
zip.file("Contents/content.hpf", contentHpf);
|
|
70
|
+
// Contents/header.xml — 최소 fontface/borderFill/charPr/tabProperties/numbering/paraPr/style
|
|
71
|
+
const header = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
|
|
72
|
+
`<hh:head ${OWPML_NS} version="1.5" secCnt="1">` +
|
|
73
|
+
`<hh:beginNum page="1" footnote="1" endnote="1" pic="1" tbl="1" equation="1"/>` +
|
|
74
|
+
`<hh:refList>` +
|
|
75
|
+
`<hh:fontfaces itemCnt="1">` +
|
|
76
|
+
`<hh:fontface lang="HANGUL" fontCnt="1">` +
|
|
77
|
+
`<hh:font id="0" face="함초롬바탕" type="TTF" isEmbedded="0"/>` +
|
|
78
|
+
`</hh:fontface>` +
|
|
79
|
+
`</hh:fontfaces>` +
|
|
80
|
+
`<hh:borderFills itemCnt="1">` +
|
|
81
|
+
`<hh:borderFill id="0" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">` +
|
|
82
|
+
`<hh:slash type="NONE" Crooked="0" isCounter="0"/>` +
|
|
83
|
+
`<hh:backSlash type="NONE" Crooked="0" isCounter="0"/>` +
|
|
84
|
+
`<hh:leftBorder type="SOLID" width="0.1 mm" color="#000000"/>` +
|
|
85
|
+
`<hh:rightBorder type="SOLID" width="0.1 mm" color="#000000"/>` +
|
|
86
|
+
`<hh:topBorder type="SOLID" width="0.1 mm" color="#000000"/>` +
|
|
87
|
+
`<hh:bottomBorder type="SOLID" width="0.1 mm" color="#000000"/>` +
|
|
88
|
+
`<hh:diagonal type="NONE" width="0.1 mm" color="#000000"/>` +
|
|
89
|
+
`</hh:borderFill>` +
|
|
90
|
+
`</hh:borderFills>` +
|
|
91
|
+
`<hh:charProperties itemCnt="1">` +
|
|
92
|
+
`<hh:charPr id="0" height="1000" textColor="#000000" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="0">` +
|
|
93
|
+
`<hh:fontRef hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>` +
|
|
94
|
+
`<hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>` +
|
|
95
|
+
`<hh:spacing hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>` +
|
|
96
|
+
`<hh:relSz hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>` +
|
|
97
|
+
`<hh:offset hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>` +
|
|
98
|
+
`</hh:charPr>` +
|
|
99
|
+
`</hh:charProperties>` +
|
|
100
|
+
`<hh:tabProperties itemCnt="1">` +
|
|
101
|
+
`<hh:tabPr id="0" autoTabLeft="1" autoTabRight="1"><hh:items itemCnt="0"/></hh:tabPr>` +
|
|
102
|
+
`</hh:tabProperties>` +
|
|
103
|
+
`<hh:numberings itemCnt="1">` +
|
|
104
|
+
`<hh:numbering id="0" start="1">` +
|
|
105
|
+
`<hh:paraHead level="1" start="1" numFormat="^1." textOffsetType="PERCENT" textOffset="50" numberingChar="false" charPrIDRef="0">` +
|
|
106
|
+
`<hh:autoNumberFormat type="DIGIT" userChar="" prefixChar="" suffixChar="."/>` +
|
|
107
|
+
`</hh:paraHead>` +
|
|
108
|
+
`</hh:numbering>` +
|
|
109
|
+
`</hh:numberings>` +
|
|
110
|
+
`<hh:paraProperties itemCnt="1">` +
|
|
111
|
+
`<hh:paraPr id="0" tabPrIDRef="0" condense="0" fontLineHeight="0" snapToGrid="0" suppressLineNumbers="0" checked="0">` +
|
|
112
|
+
`<hh:align horizontal="JUSTIFY" vertical="BASELINE"/>` +
|
|
113
|
+
`<hh:heading type="NONE" idRef="0" level="0"/>` +
|
|
114
|
+
`<hh:breakSetting breakLatinWord="KEEP_WORD" breakNonLatinWord="KEEP_WORD" widowOrphan="0" keepWithNext="0" keepLines="0" pageBreakBefore="0" lineWrap="BREAK"/>` +
|
|
115
|
+
`<hh:margin><hh:intent value="0"/><hh:left value="0"/><hh:right value="0"/><hh:prev value="0"/><hh:next value="0"/></hh:margin>` +
|
|
116
|
+
`<hh:lineSpacing type="PERCENT" value="160"/>` +
|
|
117
|
+
`</hh:paraPr>` +
|
|
118
|
+
`</hh:paraProperties>` +
|
|
119
|
+
`<hh:styles itemCnt="1">` +
|
|
120
|
+
`<hh:style id="0" type="PARA" name="바탕글" engName="Normal" paraPrIDRef="0" charPrIDRef="0" nextStyleIDRef="0" langID="1042" lockForm="0"/>` +
|
|
121
|
+
`</hh:styles>` +
|
|
122
|
+
`</hh:refList>` +
|
|
123
|
+
`</hh:head>`;
|
|
124
|
+
zip.file("Contents/header.xml", header);
|
|
125
|
+
// Contents/section0.xml — 첫 문단에 secPr, 이후 평문 줄 단위 문단
|
|
126
|
+
const bodyParas = text
|
|
127
|
+
.split(/\r?\n/)
|
|
128
|
+
.map((line) => `<hp:p id="${makeParaId()}" paraPrIDRef="0" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">` +
|
|
129
|
+
`<hp:run charPrIDRef="0">` +
|
|
130
|
+
`<hp:t>${escapeXml(line)}</hp:t>` +
|
|
131
|
+
`</hp:run>` +
|
|
132
|
+
DEFAULT_LINESEG +
|
|
133
|
+
`</hp:p>`)
|
|
134
|
+
.join("");
|
|
135
|
+
const secPrPara = `<hp:p id="${makeParaId()}" paraPrIDRef="0" styleIDRef="0" pageBreak="0" columnBreak="0" merged="0">` +
|
|
136
|
+
`<hp:run charPrIDRef="0">${SEC_PR_XML}</hp:run>` +
|
|
137
|
+
`<hp:run charPrIDRef="0"><hp:t/></hp:run>` +
|
|
138
|
+
DEFAULT_LINESEG +
|
|
139
|
+
`</hp:p>`;
|
|
140
|
+
const section0 = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n` +
|
|
141
|
+
`<hs:sec ${OWPML_NS}>` +
|
|
142
|
+
secPrPara +
|
|
143
|
+
bodyParas +
|
|
144
|
+
`</hs:sec>`;
|
|
145
|
+
zip.file("Contents/section0.xml", section0);
|
|
146
|
+
return await zip.generateAsync({ type: "uint8array" });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export default HwpxWriter;
|
package/package.json
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hwp-convert",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "HWP/HWPX ↔ Markdown/HTML 변환 + 한컴(한글)에서 실제로 열리는 HWPX 생성. 순수 TypeScript, 브라우저/Node. 표·이미지·폰트·스타일 보존.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"browser": "dist/browser/hwp-convert.browser.mjs",
|
|
10
|
+
"bin": {
|
|
11
|
+
"hwpconvert": "dist/cli.js",
|
|
12
|
+
"hwp-convert": "dist/cli.js"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"browser": "./dist/browser/hwp-convert.browser.mjs",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./browser": "./dist/browser/hwp-convert.browser.mjs"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"NOTICE",
|
|
26
|
+
"README.md",
|
|
27
|
+
"CHANGELOG.md"
|
|
28
|
+
],
|
|
29
|
+
"sideEffects": false,
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc -p tsconfig.json && npm run build:browser",
|
|
35
|
+
"build:browser": "node scripts/build-browser.mjs",
|
|
36
|
+
"clean": "rimraf dist",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest",
|
|
39
|
+
"prepare": "npm run build",
|
|
40
|
+
"prepublishOnly": "npm run clean && npm run build && npm test"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"hwp",
|
|
47
|
+
"hwpx",
|
|
48
|
+
"hwp-convert",
|
|
49
|
+
"hwp-converter",
|
|
50
|
+
"hwpx-converter",
|
|
51
|
+
"convert",
|
|
52
|
+
"converter",
|
|
53
|
+
"OWPML",
|
|
54
|
+
"CFB",
|
|
55
|
+
"OLE2",
|
|
56
|
+
"한글",
|
|
57
|
+
"한컴",
|
|
58
|
+
"한글문서",
|
|
59
|
+
"한글변환",
|
|
60
|
+
"parser",
|
|
61
|
+
"document-conversion",
|
|
62
|
+
"markdown",
|
|
63
|
+
"html",
|
|
64
|
+
"korean",
|
|
65
|
+
"typescript",
|
|
66
|
+
"browser",
|
|
67
|
+
"esm"
|
|
68
|
+
],
|
|
69
|
+
"author": "shyang <disroway@gmail.com>",
|
|
70
|
+
"repository": {
|
|
71
|
+
"type": "git",
|
|
72
|
+
"url": "git+https://github.com/shyang1012/hwp-convert.git"
|
|
73
|
+
},
|
|
74
|
+
"bugs": {
|
|
75
|
+
"url": "https://github.com/shyang1012/hwp-convert/issues"
|
|
76
|
+
},
|
|
77
|
+
"homepage": "https://github.com/shyang1012/hwp-convert#readme",
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"cfb": "^1.2.2",
|
|
80
|
+
"fast-xml-parser": "^5.2.5",
|
|
81
|
+
"htmlparser2": "^12.0.0",
|
|
82
|
+
"jszip": "^3.10.1",
|
|
83
|
+
"marked": "^18.0.2",
|
|
84
|
+
"pako": "^2.1.0"
|
|
85
|
+
},
|
|
86
|
+
"devDependencies": {
|
|
87
|
+
"@types/node": "^24.5.2",
|
|
88
|
+
"@types/pako": "^2.0.3",
|
|
89
|
+
"esbuild": "^0.28.0",
|
|
90
|
+
"rimraf": "^6.0.1",
|
|
91
|
+
"typescript": "^5.9.2",
|
|
92
|
+
"vitest": "^4.1.5"
|
|
93
|
+
}
|
|
94
|
+
}
|