@stll/docx-utils 0.0.1-placeholder.0 → 0.1.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/README.md +33 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.js +77 -0
- package/package.json +57 -3
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @stll/docx-utils
|
|
2
|
+
|
|
3
|
+
Low-level helpers for reading and writing DOCX/OOXML zip packages.
|
|
4
|
+
|
|
5
|
+
The package wraps the mechanical parts of working with a DOCX file: loading and
|
|
6
|
+
repacking the underlying zip, extracting text or binary parts, managing
|
|
7
|
+
relationships and content types, and the OOXML namespace constants those
|
|
8
|
+
operations need.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { loadDocx, extractText, ensureRelationship } from "@stll/docx-utils";
|
|
12
|
+
|
|
13
|
+
const zip = await loadDocx(bytes);
|
|
14
|
+
const text = await extractText(zip, "word/document.xml");
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
bun add @stll/docx-utils
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Exports
|
|
24
|
+
|
|
25
|
+
- `OOXML_NS` / `OoxmlPrefix` — OOXML namespace constants and prefixes.
|
|
26
|
+
- `loadDocx`, `repackZip`, `extractText`, `extractBinary`, `DOCX_COMPRESSION` —
|
|
27
|
+
zip-level read and write helpers.
|
|
28
|
+
- `findNextRId`, `ensureContentType`, `ensureRelationship` — relationship and
|
|
29
|
+
content-type management.
|
|
30
|
+
|
|
31
|
+
## License
|
|
32
|
+
|
|
33
|
+
Apache-2.0
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import JSZip from "jszip";
|
|
2
|
+
|
|
3
|
+
//#region src/namespaces.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Common OOXML namespace URIs.
|
|
6
|
+
*
|
|
7
|
+
* Canonical source for namespace constants shared across
|
|
8
|
+
* the editor (folio) and the backend (api).
|
|
9
|
+
*/
|
|
10
|
+
declare const OOXML_NS: {
|
|
11
|
+
readonly w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
12
|
+
readonly a: "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
13
|
+
readonly r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
14
|
+
readonly wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
15
|
+
readonly wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing";
|
|
16
|
+
readonly wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
|
|
17
|
+
readonly wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas";
|
|
18
|
+
readonly wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
|
|
19
|
+
readonly pic: "http://schemas.openxmlformats.org/drawingml/2006/picture";
|
|
20
|
+
readonly m: "http://schemas.openxmlformats.org/officeDocument/2006/math";
|
|
21
|
+
readonly mc: "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
22
|
+
readonly v: "urn:schemas-microsoft-com:vml";
|
|
23
|
+
readonly o: "urn:schemas-microsoft-com:office:office";
|
|
24
|
+
readonly w14: "http://schemas.microsoft.com/office/word/2010/wordml";
|
|
25
|
+
readonly w15: "http://schemas.microsoft.com/office/word/2012/wordml";
|
|
26
|
+
readonly ct: "http://schemas.openxmlformats.org/package/2006/content-types";
|
|
27
|
+
readonly pr: "http://schemas.openxmlformats.org/package/2006/relationships";
|
|
28
|
+
};
|
|
29
|
+
type OoxmlPrefix = keyof typeof OOXML_NS;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/zip.d.ts
|
|
32
|
+
/** Standard DOCX compression options */
|
|
33
|
+
declare const DOCX_COMPRESSION: {
|
|
34
|
+
type: "arraybuffer";
|
|
35
|
+
compression: "DEFLATE";
|
|
36
|
+
compressionOptions: {
|
|
37
|
+
level: number;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/** Load a DOCX file (ArrayBuffer) into a JSZip instance */
|
|
41
|
+
declare const loadDocx: (buffer: ArrayBuffer) => Promise<JSZip>;
|
|
42
|
+
/** Extract a text file from a ZIP */
|
|
43
|
+
declare const extractText: (zip: JSZip, path: string) => Promise<string | null>;
|
|
44
|
+
/** Extract a binary file from a ZIP */
|
|
45
|
+
declare const extractBinary: (zip: JSZip, path: string) => Promise<ArrayBuffer | null>;
|
|
46
|
+
/** Repack a ZIP to ArrayBuffer with standard DOCX compression */
|
|
47
|
+
declare const repackZip: (zip: JSZip) => Promise<ArrayBuffer>;
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/relationships.d.ts
|
|
50
|
+
/** Find the next available rId in a relationships XML string */
|
|
51
|
+
declare const findNextRId: (relsXml: string) => string;
|
|
52
|
+
/** Ensure a content type entry exists in [Content_Types].xml */
|
|
53
|
+
declare const ensureContentType: (contentTypesXml: string, partName: string, contentType: string) => string;
|
|
54
|
+
/** Ensure a relationship entry exists */
|
|
55
|
+
declare const ensureRelationship: (relsXml: string, rId: string, type: string, target: string) => string;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { DOCX_COMPRESSION, OOXML_NS, type OoxmlPrefix, ensureContentType, ensureRelationship, extractBinary, extractText, findNextRId, loadDocx, repackZip };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import JSZip from "jszip";
|
|
2
|
+
//#region src/namespaces.ts
|
|
3
|
+
/**
|
|
4
|
+
* Common OOXML namespace URIs.
|
|
5
|
+
*
|
|
6
|
+
* Canonical source for namespace constants shared across
|
|
7
|
+
* the editor (folio) and the backend (api).
|
|
8
|
+
*/
|
|
9
|
+
const OOXML_NS = {
|
|
10
|
+
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
|
11
|
+
a: "http://schemas.openxmlformats.org/drawingml/2006/main",
|
|
12
|
+
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
|
13
|
+
wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
|
|
14
|
+
wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
|
|
15
|
+
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
|
|
16
|
+
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
|
17
|
+
wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
|
|
18
|
+
pic: "http://schemas.openxmlformats.org/drawingml/2006/picture",
|
|
19
|
+
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
|
|
20
|
+
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
|
|
21
|
+
v: "urn:schemas-microsoft-com:vml",
|
|
22
|
+
o: "urn:schemas-microsoft-com:office:office",
|
|
23
|
+
w14: "http://schemas.microsoft.com/office/word/2010/wordml",
|
|
24
|
+
w15: "http://schemas.microsoft.com/office/word/2012/wordml",
|
|
25
|
+
ct: "http://schemas.openxmlformats.org/package/2006/content-types",
|
|
26
|
+
pr: "http://schemas.openxmlformats.org/package/2006/relationships"
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/zip.ts
|
|
30
|
+
/** Standard DOCX compression options */
|
|
31
|
+
const DOCX_COMPRESSION = {
|
|
32
|
+
type: "arraybuffer",
|
|
33
|
+
compression: "DEFLATE",
|
|
34
|
+
compressionOptions: { level: 6 }
|
|
35
|
+
};
|
|
36
|
+
/** Load a DOCX file (ArrayBuffer) into a JSZip instance */
|
|
37
|
+
const loadDocx = async (buffer) => await JSZip.loadAsync(buffer);
|
|
38
|
+
/** Extract a text file from a ZIP */
|
|
39
|
+
const extractText = async (zip, path) => {
|
|
40
|
+
const file = zip.file(path);
|
|
41
|
+
if (!file) return null;
|
|
42
|
+
return await file.async("string");
|
|
43
|
+
};
|
|
44
|
+
/** Extract a binary file from a ZIP */
|
|
45
|
+
const extractBinary = async (zip, path) => {
|
|
46
|
+
const file = zip.file(path);
|
|
47
|
+
if (!file) return null;
|
|
48
|
+
return await file.async("arraybuffer");
|
|
49
|
+
};
|
|
50
|
+
/** Repack a ZIP to ArrayBuffer with standard DOCX compression */
|
|
51
|
+
const repackZip = async (zip) => await zip.generateAsync(DOCX_COMPRESSION);
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/relationships.ts
|
|
54
|
+
/** Find the next available rId in a relationships XML string */
|
|
55
|
+
const findNextRId = (relsXml) => {
|
|
56
|
+
const matches = relsXml.matchAll(/Id="rId(?<num>\d+)"/gu);
|
|
57
|
+
let max = 0;
|
|
58
|
+
for (const m of matches) {
|
|
59
|
+
const n = Number.parseInt(m.groups?.["num"] ?? "0", 10);
|
|
60
|
+
if (n > max) max = n;
|
|
61
|
+
}
|
|
62
|
+
return `rId${max + 1}`;
|
|
63
|
+
};
|
|
64
|
+
/** Ensure a content type entry exists in [Content_Types].xml */
|
|
65
|
+
const ensureContentType = (contentTypesXml, partName, contentType) => {
|
|
66
|
+
if (contentTypesXml.includes(`PartName="${partName}"`)) return contentTypesXml;
|
|
67
|
+
const override = `<Override PartName="${partName}" ContentType="${contentType}"/>`;
|
|
68
|
+
return contentTypesXml.replace("</Types>", `${override}\n</Types>`);
|
|
69
|
+
};
|
|
70
|
+
/** Ensure a relationship entry exists */
|
|
71
|
+
const ensureRelationship = (relsXml, rId, type, target) => {
|
|
72
|
+
if (relsXml.includes(`Id="${rId}"`)) return relsXml;
|
|
73
|
+
const rel = `<Relationship Id="${rId}" Type="${type}" Target="${target}"/>`;
|
|
74
|
+
return relsXml.replace("</Relationships>", `${rel}\n</Relationships>`);
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
export { DOCX_COMPRESSION, OOXML_NS, ensureContentType, ensureRelationship, extractBinary, extractText, findNextRId, loadDocx, repackZip };
|
package/package.json
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/docx-utils",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Low-level helpers for reading and writing DOCX/OOXML zip packages: text and binary extraction, relationship and content-type management, and namespace constants.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"docx",
|
|
7
|
+
"ooxml",
|
|
8
|
+
"openxml",
|
|
9
|
+
"relationships",
|
|
10
|
+
"word",
|
|
11
|
+
"zip"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/stella/stella/tree/main/packages/docx-utils",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/stella/stella/issues"
|
|
16
|
+
},
|
|
17
|
+
"license": "Apache-2.0",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/stella/stella.git",
|
|
21
|
+
"directory": "packages/docx-utils"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"sideEffects": false,
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"clean": "git clean -xdf dist .cache .turbo node_modules",
|
|
40
|
+
"build": "tsdown",
|
|
41
|
+
"pack:dry-run": "bun pm pack --dry-run",
|
|
42
|
+
"test": "bun test src",
|
|
43
|
+
"typecheck": "tsgo --noEmit",
|
|
44
|
+
"lint": "cd ../.. && bun --bun oxlint -c oxlint.config.ts --report-unused-disable-directives-severity=error --deny-warnings --type-aware packages/docx-utils",
|
|
45
|
+
"lint:fix": "cd ../.. && bun --bun oxlint -c oxlint.config.ts --type-aware --fix packages/docx-utils",
|
|
46
|
+
"format": "oxfmt .",
|
|
47
|
+
"prepack": "bun run build"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"jszip": "3.10.1"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@stll/typescript-config": "0.0.0",
|
|
54
|
+
"@types/bun": "1.3.14",
|
|
55
|
+
"tsdown": "0.22.3"
|
|
56
|
+
},
|
|
57
|
+
"main": "./dist/index.js",
|
|
58
|
+
"types": "./dist/index.d.ts"
|
|
59
|
+
}
|