@stll/docx-utils 0.1.3 → 0.1.5

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.
@@ -0,0 +1,89 @@
1
+ //#region src/office-formats.d.ts
2
+ /** ZIP-based office formats; legacy binary formats are not XML containers. */
3
+ export declare const OFFICE_ARCHIVE_FORMATS: {
4
+ readonly docx: {
5
+ readonly family: "word";
6
+ readonly mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
7
+ };
8
+ readonly docm: {
9
+ readonly family: "word";
10
+ readonly mimeType: "application/vnd.ms-word.document.macroEnabled.12";
11
+ };
12
+ readonly dotx: {
13
+ readonly family: "word";
14
+ readonly mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.template";
15
+ };
16
+ readonly dotm: {
17
+ readonly family: "word";
18
+ readonly mimeType: "application/vnd.ms-word.template.macroEnabled.12";
19
+ };
20
+ readonly xlsx: {
21
+ readonly family: "sheet";
22
+ readonly mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
23
+ };
24
+ readonly xlsm: {
25
+ readonly family: "sheet";
26
+ readonly mimeType: "application/vnd.ms-excel.sheet.macroEnabled.12";
27
+ };
28
+ readonly xlsb: {
29
+ readonly family: "sheet";
30
+ readonly mimeType: "application/vnd.ms-excel.sheet.binary.macroEnabled.12";
31
+ };
32
+ readonly xltx: {
33
+ readonly family: "sheet";
34
+ readonly mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.template";
35
+ };
36
+ readonly xltm: {
37
+ readonly family: "sheet";
38
+ readonly mimeType: "application/vnd.ms-excel.template.macroEnabled.12";
39
+ };
40
+ readonly pptx: {
41
+ readonly family: "presentation";
42
+ readonly mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation";
43
+ };
44
+ readonly pptm: {
45
+ readonly family: "presentation";
46
+ readonly mimeType: "application/vnd.ms-powerpoint.presentation.macroEnabled.12";
47
+ };
48
+ readonly ppsx: {
49
+ readonly family: "presentation";
50
+ readonly mimeType: "application/vnd.openxmlformats-officedocument.presentationml.slideshow";
51
+ };
52
+ readonly ppsm: {
53
+ readonly family: "presentation";
54
+ readonly mimeType: "application/vnd.ms-powerpoint.slideshow.macroEnabled.12";
55
+ };
56
+ readonly potx: {
57
+ readonly family: "presentation";
58
+ readonly mimeType: "application/vnd.openxmlformats-officedocument.presentationml.template";
59
+ };
60
+ readonly potm: {
61
+ readonly family: "presentation";
62
+ readonly mimeType: "application/vnd.ms-powerpoint.template.macroEnabled.12";
63
+ };
64
+ readonly odt: {
65
+ readonly family: "odf";
66
+ readonly mimeType: "application/vnd.oasis.opendocument.text";
67
+ };
68
+ readonly ods: {
69
+ readonly family: "odf";
70
+ readonly mimeType: "application/vnd.oasis.opendocument.spreadsheet";
71
+ };
72
+ readonly odp: {
73
+ readonly family: "odf";
74
+ readonly mimeType: "application/vnd.oasis.opendocument.presentation";
75
+ };
76
+ readonly ott: {
77
+ readonly family: "odf";
78
+ readonly mimeType: "application/vnd.oasis.opendocument.text-template";
79
+ };
80
+ readonly ots: {
81
+ readonly family: "odf";
82
+ readonly mimeType: "application/vnd.oasis.opendocument.spreadsheet-template";
83
+ };
84
+ readonly otp: {
85
+ readonly family: "odf";
86
+ readonly mimeType: "application/vnd.oasis.opendocument.presentation-template";
87
+ };
88
+ };
89
+ //#endregion
@@ -0,0 +1,90 @@
1
+ //#region src/office-formats.ts
2
+ /** ZIP-based office formats; legacy binary formats are not XML containers. */
3
+ const OFFICE_ARCHIVE_FORMATS = {
4
+ docx: {
5
+ family: "word",
6
+ mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
7
+ },
8
+ docm: {
9
+ family: "word",
10
+ mimeType: "application/vnd.ms-word.document.macroEnabled.12"
11
+ },
12
+ dotx: {
13
+ family: "word",
14
+ mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.template"
15
+ },
16
+ dotm: {
17
+ family: "word",
18
+ mimeType: "application/vnd.ms-word.template.macroEnabled.12"
19
+ },
20
+ xlsx: {
21
+ family: "sheet",
22
+ mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
23
+ },
24
+ xlsm: {
25
+ family: "sheet",
26
+ mimeType: "application/vnd.ms-excel.sheet.macroEnabled.12"
27
+ },
28
+ xlsb: {
29
+ family: "sheet",
30
+ mimeType: "application/vnd.ms-excel.sheet.binary.macroEnabled.12"
31
+ },
32
+ xltx: {
33
+ family: "sheet",
34
+ mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.template"
35
+ },
36
+ xltm: {
37
+ family: "sheet",
38
+ mimeType: "application/vnd.ms-excel.template.macroEnabled.12"
39
+ },
40
+ pptx: {
41
+ family: "presentation",
42
+ mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
43
+ },
44
+ pptm: {
45
+ family: "presentation",
46
+ mimeType: "application/vnd.ms-powerpoint.presentation.macroEnabled.12"
47
+ },
48
+ ppsx: {
49
+ family: "presentation",
50
+ mimeType: "application/vnd.openxmlformats-officedocument.presentationml.slideshow"
51
+ },
52
+ ppsm: {
53
+ family: "presentation",
54
+ mimeType: "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"
55
+ },
56
+ potx: {
57
+ family: "presentation",
58
+ mimeType: "application/vnd.openxmlformats-officedocument.presentationml.template"
59
+ },
60
+ potm: {
61
+ family: "presentation",
62
+ mimeType: "application/vnd.ms-powerpoint.template.macroEnabled.12"
63
+ },
64
+ odt: {
65
+ family: "odf",
66
+ mimeType: "application/vnd.oasis.opendocument.text"
67
+ },
68
+ ods: {
69
+ family: "odf",
70
+ mimeType: "application/vnd.oasis.opendocument.spreadsheet"
71
+ },
72
+ odp: {
73
+ family: "odf",
74
+ mimeType: "application/vnd.oasis.opendocument.presentation"
75
+ },
76
+ ott: {
77
+ family: "odf",
78
+ mimeType: "application/vnd.oasis.opendocument.text-template"
79
+ },
80
+ ots: {
81
+ family: "odf",
82
+ mimeType: "application/vnd.oasis.opendocument.spreadsheet-template"
83
+ },
84
+ otp: {
85
+ family: "odf",
86
+ mimeType: "application/vnd.oasis.opendocument.presentation-template"
87
+ }
88
+ };
89
+ //#endregion
90
+ export { OFFICE_ARCHIVE_FORMATS };
@@ -0,0 +1,38 @@
1
+ import { Attr, Document, Element } from "slimdom";
2
+ //#region src/office-metadata.d.ts
3
+ export declare const officeIdentityAttributePolicy: (name: string) => {
4
+ readonly type: "replace";
5
+ readonly replacement: "Author";
6
+ } | {
7
+ readonly type: "replace";
8
+ readonly replacement: "A";
9
+ } | {
10
+ readonly type: "remove";
11
+ } | {
12
+ readonly type: "remove";
13
+ } | {
14
+ readonly type: "replace";
15
+ readonly replacement: "Author";
16
+ } | {
17
+ readonly type: "remove";
18
+ } | {
19
+ readonly type: "remove";
20
+ } | {
21
+ readonly type: "replace";
22
+ readonly replacement: "Author";
23
+ } | undefined;
24
+ export declare const isOfficeCollaborationPart: (part: string) => boolean;
25
+ /** All XML parts in which office producers store properties or collaboration identities. */
26
+ export declare const isOfficeIdentityPart: (part: string) => boolean;
27
+ export type OfficeIdentityField = {
28
+ type: "text";
29
+ node: Element;
30
+ field: string;
31
+ } | {
32
+ type: "attribute";
33
+ node: Attr;
34
+ field: string;
35
+ };
36
+ /** Internal reference IDs and document/comment body text are deliberately excluded. */
37
+ export declare const officeIdentityFields: (document: Document, part: string) => OfficeIdentityField[];
38
+ //#endregion
@@ -0,0 +1,88 @@
1
+ //#region src/office-metadata.ts
2
+ const PROPERTY_FIELDS = /* @__PURE__ */ new Set([
3
+ "creator",
4
+ "lastmodifiedby",
5
+ "company",
6
+ "manager",
7
+ "template",
8
+ "title",
9
+ "subject",
10
+ "keywords",
11
+ "keyword",
12
+ "description",
13
+ "initial-creator",
14
+ "printed-by",
15
+ "user-defined",
16
+ "category",
17
+ "contentstatus"
18
+ ]);
19
+ const PROPERTY_ATTRIBUTES = /* @__PURE__ */ new Set([
20
+ "href",
21
+ "name",
22
+ "title"
23
+ ]);
24
+ const OFFICE_IDENTITY_ATTRIBUTE_POLICIES = {
25
+ author: {
26
+ type: "replace",
27
+ replacement: "Author"
28
+ },
29
+ initials: {
30
+ type: "replace",
31
+ replacement: "A"
32
+ },
33
+ userid: { type: "remove" },
34
+ providerid: { type: "remove" },
35
+ displayname: {
36
+ type: "replace",
37
+ replacement: "Author"
38
+ },
39
+ email: { type: "remove" },
40
+ emailaddress: { type: "remove" },
41
+ name: {
42
+ type: "replace",
43
+ replacement: "Author"
44
+ }
45
+ };
46
+ const IDENTITY_ATTRIBUTES = new Set(Object.keys(OFFICE_IDENTITY_ATTRIBUTE_POLICIES).filter((name) => name !== "name"));
47
+ const officeIdentityAttributePolicy = (name) => Object.entries(OFFICE_IDENTITY_ATTRIBUTE_POLICIES).find(([key]) => key === name.toLowerCase())?.[1];
48
+ const isOfficeCollaborationPart = (part) => /^(?:content\.xml|(?:word|xl|ppt)\/.*\.xml)$/iu.test(part);
49
+ const NAMED_IDENTITIES = /* @__PURE__ */ new Set([
50
+ "person",
51
+ "author",
52
+ "cmauthor",
53
+ "commentauthor",
54
+ "mention"
55
+ ]);
56
+ const DC_NAMESPACE = "http://purl.org/dc/elements/1.1/";
57
+ /** All XML parts in which office producers store properties or collaboration identities. */
58
+ const isOfficeIdentityPart = (part) => /^(?:docProps\/(?:core|app|custom)\.xml|meta\.xml)$/iu.test(part) || isOfficeCollaborationPart(part);
59
+ /** Internal reference IDs and document/comment body text are deliberately excluded. */
60
+ const officeIdentityFields = (document, part) => {
61
+ const result = [];
62
+ const propertyPart = /^(?:docProps\/(?:core|app)\.xml|meta\.xml)$/iu.test(part);
63
+ const customPart = /^docProps\/custom\.xml$/iu.test(part);
64
+ for (const element of document.getElementsByTagNameNS("*", "*")) {
65
+ const name = element.localName.toLowerCase();
66
+ const propertyField = propertyPart && PROPERTY_FIELDS.has(name);
67
+ const customField = customPart && name === "property";
68
+ const authorText = /^xl\/comments[^/]*\.xml$/iu.test(part) && name === "author";
69
+ const odfCreator = part === "content.xml" && element.namespaceURI === DC_NAMESPACE && name === "creator";
70
+ if (propertyField || customField || authorText || odfCreator) result.push({
71
+ type: "text",
72
+ node: element,
73
+ field: element.localName
74
+ });
75
+ for (const attribute of element.attributes) {
76
+ const attr = attribute.localName.toLowerCase();
77
+ if (!(propertyField && PROPERTY_ATTRIBUTES.has(attr) || customField && attr === "name" || !propertyPart && !customPart && (IDENTITY_ATTRIBUTES.has(attr) || attr === "name" && NAMED_IDENTITIES.has(name)))) continue;
78
+ result.push({
79
+ type: "attribute",
80
+ node: attribute,
81
+ field: `${element.localName}@${attribute.localName}`
82
+ });
83
+ }
84
+ }
85
+ return result;
86
+ };
87
+ //#endregion
88
+ export { isOfficeCollaborationPart, isOfficeIdentityPart, officeIdentityAttributePolicy, officeIdentityFields };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/docx-utils",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
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
5
  "keywords": [
6
6
  "docx",
@@ -30,6 +30,14 @@
30
30
  ".": {
31
31
  "types": "./dist/index.d.ts",
32
32
  "import": "./dist/index.js"
33
+ },
34
+ "./office-formats": {
35
+ "types": "./dist/office-formats.d.ts",
36
+ "import": "./dist/office-formats.js"
37
+ },
38
+ "./office-metadata": {
39
+ "types": "./dist/office-metadata.d.ts",
40
+ "import": "./dist/office-metadata.js"
33
41
  }
34
42
  },
35
43
  "publishConfig": {
@@ -40,12 +48,14 @@
40
48
  "build": "tsdown",
41
49
  "pack:dry-run": "bun pm pack --dry-run",
42
50
  "test": "bun test src",
51
+ "check:office-fixture-metadata": "bun scripts/check-office-fixture-metadata.ts",
52
+ "test:office-fixture-metadata": "bun test scripts/check-office-fixture-metadata.test.ts",
43
53
  "typecheck": "bun ../../packages/scripts/src/tsc-native.ts --noEmit",
44
54
  "lint": "cd ../.. && bun --bun oxlint -c oxlint.config.ts --report-unused-disable-directives-severity=error --type-aware --type-check packages/docx-utils",
45
55
  "lint:fix": "cd ../.. && bun --bun oxlint -c oxlint.config.ts --type-aware --fix packages/docx-utils",
46
56
  "format": "bun ../../scripts/run-oxfmt.ts .",
47
57
  "prepack": "bun run build",
48
- "test:property": "bun test --preload @stll/property-testing/preload $(grep -rlF 'fc.assert' src --include='*.test.ts')"
58
+ "test:property": "bun test --preload @stll/property-testing/preload $(grep -rlE 'fc\\.assert|assertProperty' src --include='*.test.ts')"
49
59
  },
50
60
  "dependencies": {
51
61
  "better-result": "3.0.1",