@office-open/docx 0.9.1 → 0.9.3
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/{context-DkABanLH.mjs → context-DeKZoZem.mjs} +107 -155
- package/dist/context-DeKZoZem.mjs.map +1 -0
- package/dist/{core-properties-C79Z-ZPE.d.mts → core-properties-D9dBbZtc.d.mts} +786 -772
- package/dist/core-properties-D9dBbZtc.d.mts.map +1 -0
- package/dist/{document-Ch4dyBB4.mjs → document-D8HDkCHs.mjs} +353 -11
- package/dist/document-D8HDkCHs.mjs.map +1 -0
- package/dist/{generate-DQ6qeP58.mjs → generate-DjkvEWjY.mjs} +3 -3
- package/dist/{generate-DQ6qeP58.mjs.map → generate-DjkvEWjY.mjs.map} +1 -1
- package/dist/generate.d.mts +1 -1
- package/dist/generate.mjs +1 -1
- package/dist/index.d.mts +3 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -5
- package/dist/{parse-0XGa3h9q.mjs → parse-CR5VbXbs.mjs} +3 -3
- package/dist/parse-CR5VbXbs.mjs.map +1 -0
- package/dist/parse.d.mts +1 -1
- package/dist/parse.mjs +1 -1
- package/dist/patch/index.d.mts +1 -1
- package/dist/patch/index.d.mts.map +1 -1
- package/dist/patch/index.mjs +2 -2
- package/dist/patch/index.mjs.map +1 -1
- package/package.json +3 -3
- package/dist/context-DkABanLH.mjs.map +0 -1
- package/dist/core-properties-C79Z-ZPE.d.mts.map +0 -1
- package/dist/document-Ch4dyBB4.mjs.map +0 -1
- package/dist/parse-0XGa3h9q.mjs.map +0 -1
package/dist/patch/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/patch/from-docx.ts","../../src/patch/patch-detector.ts"],"sourcesContent":["import { TargetModeType } from \"@office-open/core\";\nimport {\n DOCX_NS,\n OoxmlMimeType,\n appendContentType,\n appendRelationship,\n createReplacer,\n getNextRelationshipIndex,\n getReferencedMedia,\n replaceImagePlaceholders,\n strFromU8,\n toJson,\n unzipSync,\n zipAndConvert,\n} from \"@office-open/core\";\nimport type { OutputByType, OutputType } from \"@office-open/core\";\nimport { toUint8Array } from \"@office-open/core\";\nimport { escapeXml, js2xml, xml2js } from \"@office-open/xml\";\nimport type { Element } from \"@office-open/xml\";\nimport { DocumentAttributeNamespaces } from \"@parts/document\";\nimport { stringifyJsonChild, stringifyParagraphInline, stringifyRunInline } from \"@parts/inline\";\nimport type { ParagraphChild } from \"@parts/inline\";\nimport type { ParagraphOptions } from \"@parts/paragraph/paragraph\";\nimport type { RunOptions } from \"@parts/paragraph/run/run\";\nimport { tableDesc } from \"@parts/table/descriptor\";\nimport type { TableOptions } from \"@parts/table/table\";\nimport { Media } from \"@shared/media\";\nimport type { SectionChild } from \"@shared/section\";\n\nimport type { BodyContext } from \"../context\";\nimport type { ViewWrapper } from \"../context\";\n\n/** Reusable TextEncoder (stateless, safe to share). */\nconst encoder = new TextEncoder();\n\n/**\n * Document patching module for modifying existing .docx files.\n *\n * Uses compile-path stringifiers (zero class instantiation) to serialize\n * patch content — no Formatter, no XmlComponent instances.\n *\n * @module\n */\n\n// ── Patch content stringification ──\n\n/**\n * Lightweight BodyContext adapter for patch serialization.\n * Captures hyperlink and image relationships for post-processing.\n */\nfunction createPatchContext(\n file: { media: Media },\n hyperlinkSink: Array<{ id: string; link: string }>,\n): BodyContext {\n return {\n fileData: file as unknown as BodyContext[\"fileData\"],\n file: file as unknown as BodyContext[\"file\"],\n viewWrapper: {\n relationships: {\n addRelationship: (linkId: string, _type: string, target: string, _mode?: string) => {\n hyperlinkSink.push({ id: linkId, link: target });\n },\n relationshipCount: 0,\n },\n } as unknown as BodyContext[\"viewWrapper\"],\n stringifyChild: () => \"\",\n addRelationship: () => \"\",\n addMedia: () => \"\",\n };\n}\n\nconst docxReplacer = createReplacer({\n ns: DOCX_NS,\n formatChild: (child: unknown): Element[] => {\n let xmlStr: string;\n\n if (typeof child === \"string\") {\n // Plain string → simple run\n xmlStr = `<w:r><w:t xml:space=\"preserve\">${escapeXml(child)}</w:t></w:r>`;\n } else if (typeof child === \"object\" && child !== null) {\n const obj = child as Record<string, unknown>;\n // SectionChild level (paragraph / table) — for DOCUMENT patches\n if (\"paragraph\" in obj) {\n xmlStr = stringifyParagraphInline(obj.paragraph as ParagraphOptions, currentPatchCtx);\n } else if (\"table\" in obj) {\n xmlStr = tableDesc.stringify(obj.table as TableOptions, currentPatchCtx) ?? \"\";\n } else {\n // ParagraphChild level — for PARAGRAPH patches\n // Try compile-path JSON child dispatch first\n const jr = stringifyJsonChild(child as ParagraphChild, currentPatchCtx);\n if (jr !== undefined) {\n xmlStr = Array.isArray(jr) ? jr.join(\"\") : jr;\n } else {\n // RunOptions (plain objects with text/children/bold/etc.)\n xmlStr = stringifyRunInline(child as RunOptions, currentPatchCtx);\n }\n }\n } else {\n xmlStr = \"<w:r/>\";\n }\n\n const jsonObj = xml2js(xmlStr, { captureSpacesBetweenElements: true });\n return [jsonObj.elements![0]];\n },\n});\n\n/** Current patch context — set per file in the main loop. */\nlet currentPatchCtx: BodyContext;\n\n/**\n * Supported input data types for document patching.\n */\nexport type InputDataType = Buffer | string | number[] | Uint8Array | ArrayBuffer | Blob;\n\n/**\n * Patch type enumeration.\n *\n * @publicApi\n */\nexport const PatchType = {\n DOCUMENT: \"file\",\n PARAGRAPH: \"paragraph\",\n} as const;\n\ninterface ParagraphPatch {\n type: typeof PatchType.PARAGRAPH;\n children: unknown[];\n}\n\ninterface FilePatch {\n type: typeof PatchType.DOCUMENT;\n children: SectionChild[];\n}\n\ninterface ImageRelationshipAddition {\n key: string;\n mediaDatas: { fileName: string }[];\n}\n\ninterface HyperlinkRelationshipAddition {\n key: string;\n hyperlink: { id: string; link: string };\n}\n\nexport type Patch = ParagraphPatch | FilePatch;\n\nexport type PatchDocumentOutputType = OutputType;\n\nexport interface PatchDocumentOptions<T extends PatchDocumentOutputType = PatchDocumentOutputType> {\n outputType: T;\n data: InputDataType;\n patches: Readonly<Record<string, Patch>>;\n keepOriginalStyles?: boolean;\n placeholderDelimiters?: Readonly<{\n start: string;\n end: string;\n }>;\n recursive?: boolean;\n}\n\nconst UTF16LE = new Uint8Array([0xff, 0xfe]);\nconst UTF16BE = new Uint8Array([0xfe, 0xff]);\n\nconst compareByteArrays = (a: Uint8Array, b: Uint8Array): boolean => {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\n\n/**\n * Patches an existing .docx document by replacing placeholders with new content.\n *\n * @publicApi\n */\nexport const patchDocument = async <T extends PatchDocumentOutputType = PatchDocumentOutputType>({\n outputType,\n data,\n patches,\n keepOriginalStyles = true,\n placeholderDelimiters = { end: \"}}\", start: \"{{\" } as const,\n recursive = true,\n}: PatchDocumentOptions<T>): Promise<OutputByType[T]> => {\n const zipContent = unzipSync(toUint8Array(data));\n const contexts = new Map<string, BodyContext>();\n const media = new Media();\n const file = { media } as BodyContext[\"file\"];\n\n const map = new Map<string, Element>();\n\n const imageRelationshipAdditions: ImageRelationshipAddition[] = [];\n const hyperlinkRelationshipAdditions: HyperlinkRelationshipAddition[] = [];\n let hasMedia = false;\n\n const binaryContentMap = new Map<string, Uint8Array>();\n\n for (const [key, value] of Object.entries(zipContent)) {\n const startBytes = value.slice(0, 2);\n if (compareByteArrays(startBytes, UTF16LE) || compareByteArrays(startBytes, UTF16BE)) {\n binaryContentMap.set(key, value);\n continue;\n }\n\n if (!key.endsWith(\".xml\") && !key.endsWith(\".rels\")) {\n binaryContentMap.set(key, value);\n continue;\n }\n\n const json = toJson(strFromU8(value));\n\n if (key === \"word/document.xml\") {\n const document = json.elements?.find((i) => i.name === \"w:document\");\n if (document && document.attributes) {\n for (const ns of [\"mc\", \"wp\", \"r\", \"w15\", \"m\"] as const) {\n document.attributes[`xmlns:${ns}`] = DocumentAttributeNamespaces[ns];\n }\n document.attributes[\"mc:Ignorable\"] =\n `${document.attributes[\"mc:Ignorable\"] || \"\"} w15`.trim();\n }\n }\n\n if (key.startsWith(\"word/\") && !key.endsWith(\".xml.rels\")) {\n const hyperlinkSink: Array<{ id: string; link: string }> = [];\n\n const context: BodyContext = {\n fileData: file,\n file,\n viewWrapper: {\n relationships: {\n addRelationship: (\n linkId: string,\n _: string,\n target: string,\n __: (typeof TargetModeType)[keyof typeof TargetModeType],\n ) => {\n hyperlinkRelationshipAdditions.push({\n hyperlink: {\n id: linkId,\n link: target,\n },\n key,\n });\n },\n },\n } as unknown as ViewWrapper,\n stringifyChild: () => \"\",\n addRelationship: () => \"\",\n addMedia: () => \"\",\n };\n contexts.set(key, context);\n\n if (!placeholderDelimiters?.start.trim() || !placeholderDelimiters?.end.trim()) {\n throw new Error(\"Both start and end delimiters must be non-empty strings.\");\n }\n\n const { start, end } = placeholderDelimiters;\n\n // Create compile-path context for stringifying patch children\n const patchCtx = createPatchContext(file, hyperlinkSink);\n currentPatchCtx = patchCtx;\n\n for (const [patchKey, patchValue] of Object.entries(patches)) {\n const patchText = `${start}${patchKey}${end}`;\n while (true) {\n const { didFindOccurrence } = docxReplacer({\n context,\n json,\n keepOriginalStyles,\n patch: patchValue,\n patchText,\n });\n if (!recursive || !didFindOccurrence) {\n break;\n }\n }\n }\n\n // Flush hyperlink relationships captured by the compile-path context\n for (const hl of hyperlinkSink) {\n hyperlinkRelationshipAdditions.push({\n hyperlink: { id: hl.id, link: hl.link },\n key,\n });\n }\n\n const mediaDatas = getReferencedMedia(JSON.stringify(json), media.array);\n if (mediaDatas.length > 0) {\n hasMedia = true;\n imageRelationshipAdditions.push({\n key,\n mediaDatas,\n });\n }\n }\n\n map.set(key, json);\n }\n\n for (const { key, mediaDatas } of imageRelationshipAdditions) {\n const relationshipKey = `word/_rels/${key.split(\"/\").pop()}.rels`;\n const relationshipsJson = map.get(relationshipKey) ?? createRelationshipFile();\n map.set(relationshipKey, relationshipsJson);\n\n const index = getNextRelationshipIndex(relationshipsJson);\n const newJson = replaceImagePlaceholders(\n JSON.stringify(map.get(key)),\n mediaDatas,\n index,\n \"plain\",\n );\n map.set(key, JSON.parse(newJson) as Element);\n\n for (let i = 0; i < mediaDatas.length; i++) {\n const { fileName } = mediaDatas[i];\n appendRelationship(\n relationshipsJson,\n index + i,\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\",\n `media/${fileName}`,\n );\n }\n }\n\n for (const { key, hyperlink } of hyperlinkRelationshipAdditions) {\n const relationshipKey = `word/_rels/${key.split(\"/\").pop()}.rels`;\n\n const relationshipsJson = map.get(relationshipKey) ?? createRelationshipFile();\n map.set(relationshipKey, relationshipsJson);\n\n appendRelationship(\n relationshipsJson,\n hyperlink.id,\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\",\n hyperlink.link,\n TargetModeType.EXTERNAL,\n );\n }\n\n if (hasMedia) {\n const contentTypesJson = map.get(\"[Content_Types].xml\");\n\n if (!contentTypesJson) {\n throw new Error(\"Could not find content types file\");\n }\n\n appendContentType(contentTypesJson, \"image/png\", \"png\");\n appendContentType(contentTypesJson, \"image/jpeg\", \"jpeg\");\n appendContentType(contentTypesJson, \"image/jpeg\", \"jpg\");\n appendContentType(contentTypesJson, \"image/bmp\", \"bmp\");\n appendContentType(contentTypesJson, \"image/gif\", \"gif\");\n appendContentType(contentTypesJson, \"image/svg+xml\", \"svg\");\n }\n\n const files: Record<string, Uint8Array> = {};\n\n for (const [key, value] of map) {\n files[key] = encoder.encode(js2xml(value));\n }\n\n for (const [key, value] of binaryContentMap) {\n files[key] = value;\n }\n\n for (const { data: mediaData, fileName } of media.array) {\n files[`word/media/${fileName}`] =\n mediaData instanceof Uint8Array ? mediaData : new Uint8Array(mediaData);\n }\n\n return await zipAndConvert(files, outputType, OoxmlMimeType.DOCX);\n};\n\nconst createRelationshipFile = (): Element => ({\n declaration: {\n attributes: {\n encoding: \"UTF-8\",\n standalone: \"yes\",\n version: \"1.0\",\n },\n },\n elements: [\n {\n attributes: {\n xmlns: \"http://schemas.openxmlformats.org/package/2006/relationships\",\n },\n elements: [],\n name: \"Relationships\",\n type: \"element\",\n },\n ],\n});\n","/**\n * Patch detector for discovering placeholders in document templates.\n *\n * @module\n */\nimport { DOCX_NS, createTraverser, strFromU8, toJson, unzipSync } from \"@office-open/core\";\nimport { toUint8Array } from \"@office-open/core\";\n\nimport type { InputDataType } from \"./from-docx\";\n\n/**\n * Options for patch detection.\n *\n * @property data - The document template to scan for placeholders\n */\ninterface PatchDetectorOptions {\n data: InputDataType;\n}\n\n/**\n * Detects all placeholders present in a document template.\n *\n * Scans through all XML content in a .docx file to find placeholder text\n * enclosed in delimiters (default: {{placeholder}}). This is useful for\n * discovering what patches a template expects before performing replacement.\n *\n * @param options - Patch detector configuration\n * @returns Array of placeholder keys found in the document\n *\n * @example\n * ```typescript\n * const placeholders = await patchDetector({ data: templateBuffer });\n * // Returns: [\"name\", \"date\", \"address\"] if template contains {{name}}, {{date}}, {{address}}\n *\n * // Use detected placeholders to create patches\n * const patches = {};\n * for (const key of placeholders) {\n * patches[key] = {\n * type: PatchType.PARAGRAPH,\n * children: [new TextRun(getUserData(key))],\n * };\n * });\n * ```\n */\nexport const patchDetector = async ({ data }: PatchDetectorOptions): Promise<string[]> => {\n const zipContent = unzipSync(toUint8Array(data));\n const patches = new Set<string>();\n\n for (const [key, value] of Object.entries(zipContent)) {\n if (!key.endsWith(\".xml\") && !key.endsWith(\".rels\")) {\n continue;\n }\n if (key.startsWith(\"word/\") && !key.endsWith(\".xml.rels\")) {\n const json = toJson(strFromU8(value));\n const { traverse } = createTraverser(DOCX_NS);\n for (const p of traverse(json)) {\n for (const patch of findPatchKeys(p.text)) {\n patches.add(patch);\n }\n }\n }\n }\n return [...patches];\n};\n\n/**\n * Extracts placeholder keys from text using regex pattern.\n *\n * @param text - Text to search for placeholders\n * @returns Array of placeholder keys (without delimiters)\n */\nconst findPatchKeys = (text: string): string[] => {\n const pattern = /(?<=\\{\\{).+?(?=\\}\\})/gs;\n return text.match(pattern) ?? [];\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/patch/from-docx.ts","../../src/patch/patch-detector.ts"],"sourcesContent":["import { TargetModeType } from \"@office-open/core\";\nimport {\n DOCX_NS,\n OoxmlMimeType,\n appendContentType,\n appendRelationship,\n createReplacer,\n getNextRelationshipIndex,\n getReferencedMedia,\n replaceImagePlaceholders,\n strFromU8,\n toJson,\n unzipSync,\n zipAndConvert,\n} from \"@office-open/core\";\nimport type { OutputByType, OutputType } from \"@office-open/core\";\nimport { toUint8Array } from \"@office-open/core\";\nimport { escapeXml, js2xml, xml2js } from \"@office-open/xml\";\nimport type { Element } from \"@office-open/xml\";\nimport { DocumentAttributeNamespaces } from \"@parts/document\";\nimport {\n stringifyChildDispatch,\n stringifyParagraphInline,\n stringifyRunInline,\n} from \"@parts/inline\";\nimport type { ParagraphChild } from \"@parts/paragraph/paragraph\";\nimport type { ParagraphOptions } from \"@parts/paragraph/paragraph\";\nimport type { RunOptions } from \"@parts/paragraph/run/run\";\nimport { tableDesc } from \"@parts/table/descriptor\";\nimport type { TableOptions } from \"@parts/table/table\";\nimport { Media } from \"@shared/media\";\nimport type { SectionChild } from \"@shared/section\";\n\nimport type { BodyContext } from \"../context\";\nimport type { ViewWrapper } from \"../context\";\n\n/** Reusable TextEncoder (stateless, safe to share). */\nconst encoder = new TextEncoder();\n\n/**\n * Document patching module for modifying existing .docx files.\n *\n * Uses compile-path stringifiers (zero class instantiation) to serialize\n * patch content — no Formatter, no XmlComponent instances.\n *\n * @module\n */\n\n// ── Patch content stringification ──\n\n/**\n * Lightweight BodyContext adapter for patch serialization.\n * Captures hyperlink and image relationships for post-processing.\n */\nfunction createPatchContext(\n file: { media: Media },\n hyperlinkSink: Array<{ id: string; link: string }>,\n): BodyContext {\n return {\n fileData: file as unknown as BodyContext[\"fileData\"],\n file: file as unknown as BodyContext[\"file\"],\n viewWrapper: {\n relationships: {\n addRelationship: (linkId: string, _type: string, target: string, _mode?: string) => {\n hyperlinkSink.push({ id: linkId, link: target });\n },\n relationshipCount: 0,\n },\n } as unknown as BodyContext[\"viewWrapper\"],\n stringifyChild: () => \"\",\n addRelationship: () => \"\",\n addMedia: () => \"\",\n };\n}\n\nconst docxReplacer = createReplacer({\n ns: DOCX_NS,\n formatChild: (child: unknown): Element[] => {\n let xmlStr: string;\n\n if (typeof child === \"string\") {\n // Plain string → simple run\n xmlStr = `<w:r><w:t xml:space=\"preserve\">${escapeXml(child)}</w:t></w:r>`;\n } else if (typeof child === \"object\" && child !== null) {\n const obj = child as Record<string, unknown>;\n // SectionChild level (paragraph / table) — for DOCUMENT patches\n if (\"paragraph\" in obj) {\n xmlStr = stringifyParagraphInline(obj.paragraph as ParagraphOptions, currentPatchCtx);\n } else if (\"table\" in obj) {\n xmlStr = tableDesc.stringify(obj.table as TableOptions, currentPatchCtx) ?? \"\";\n } else {\n // ParagraphChild level — for PARAGRAPH patches\n // Try compile-path JSON child dispatch first\n const jr = stringifyChildDispatch(child as ParagraphChild, currentPatchCtx);\n if (jr !== undefined) {\n xmlStr = Array.isArray(jr) ? jr.join(\"\") : jr;\n } else {\n // RunOptions (plain objects with text/children/bold/etc.)\n xmlStr = stringifyRunInline(child as RunOptions, currentPatchCtx);\n }\n }\n } else {\n xmlStr = \"<w:r/>\";\n }\n\n const jsonObj = xml2js(xmlStr, { captureSpacesBetweenElements: true });\n return [jsonObj.elements![0]];\n },\n});\n\n/** Current patch context — set per file in the main loop. */\nlet currentPatchCtx: BodyContext;\n\n/**\n * Supported input data types for document patching.\n */\nexport type InputDataType = Buffer | string | number[] | Uint8Array | ArrayBuffer | Blob;\n\n/**\n * Patch type enumeration.\n *\n * @publicApi\n */\nexport const PatchType = {\n DOCUMENT: \"file\",\n PARAGRAPH: \"paragraph\",\n} as const;\n\ninterface ParagraphPatch {\n type: typeof PatchType.PARAGRAPH;\n children: unknown[];\n}\n\ninterface FilePatch {\n type: typeof PatchType.DOCUMENT;\n children: SectionChild[];\n}\n\ninterface ImageRelationshipAddition {\n key: string;\n mediaDatas: { fileName: string }[];\n}\n\ninterface HyperlinkRelationshipAddition {\n key: string;\n hyperlink: { id: string; link: string };\n}\n\nexport type Patch = ParagraphPatch | FilePatch;\n\nexport type PatchDocumentOutputType = OutputType;\n\nexport interface PatchDocumentOptions<T extends PatchDocumentOutputType = PatchDocumentOutputType> {\n outputType: T;\n data: InputDataType;\n patches: Readonly<Record<string, Patch>>;\n keepOriginalStyles?: boolean;\n placeholderDelimiters?: Readonly<{\n start: string;\n end: string;\n }>;\n recursive?: boolean;\n}\n\nconst UTF16LE = new Uint8Array([0xff, 0xfe]);\nconst UTF16BE = new Uint8Array([0xfe, 0xff]);\n\nconst compareByteArrays = (a: Uint8Array, b: Uint8Array): boolean => {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\n\n/**\n * Patches an existing .docx document by replacing placeholders with new content.\n *\n * @publicApi\n */\nexport const patchDocument = async <T extends PatchDocumentOutputType = PatchDocumentOutputType>({\n outputType,\n data,\n patches,\n keepOriginalStyles = true,\n placeholderDelimiters = { end: \"}}\", start: \"{{\" } as const,\n recursive = true,\n}: PatchDocumentOptions<T>): Promise<OutputByType[T]> => {\n const zipContent = unzipSync(toUint8Array(data));\n const contexts = new Map<string, BodyContext>();\n const media = new Media();\n const file = { media } as BodyContext[\"file\"];\n\n const map = new Map<string, Element>();\n\n const imageRelationshipAdditions: ImageRelationshipAddition[] = [];\n const hyperlinkRelationshipAdditions: HyperlinkRelationshipAddition[] = [];\n let hasMedia = false;\n\n const binaryContentMap = new Map<string, Uint8Array>();\n\n for (const [key, value] of Object.entries(zipContent)) {\n const startBytes = value.slice(0, 2);\n if (compareByteArrays(startBytes, UTF16LE) || compareByteArrays(startBytes, UTF16BE)) {\n binaryContentMap.set(key, value);\n continue;\n }\n\n if (!key.endsWith(\".xml\") && !key.endsWith(\".rels\")) {\n binaryContentMap.set(key, value);\n continue;\n }\n\n const json = toJson(strFromU8(value));\n\n if (key === \"word/document.xml\") {\n const document = json.elements?.find((i) => i.name === \"w:document\");\n if (document && document.attributes) {\n for (const ns of [\"mc\", \"wp\", \"r\", \"w15\", \"m\"] as const) {\n document.attributes[`xmlns:${ns}`] = DocumentAttributeNamespaces[ns];\n }\n document.attributes[\"mc:Ignorable\"] =\n `${document.attributes[\"mc:Ignorable\"] || \"\"} w15`.trim();\n }\n }\n\n if (key.startsWith(\"word/\") && !key.endsWith(\".xml.rels\")) {\n const hyperlinkSink: Array<{ id: string; link: string }> = [];\n\n const context: BodyContext = {\n fileData: file,\n file,\n viewWrapper: {\n relationships: {\n addRelationship: (\n linkId: string,\n _: string,\n target: string,\n __: (typeof TargetModeType)[keyof typeof TargetModeType],\n ) => {\n hyperlinkRelationshipAdditions.push({\n hyperlink: {\n id: linkId,\n link: target,\n },\n key,\n });\n },\n },\n } as unknown as ViewWrapper,\n stringifyChild: () => \"\",\n addRelationship: () => \"\",\n addMedia: () => \"\",\n };\n contexts.set(key, context);\n\n if (!placeholderDelimiters?.start.trim() || !placeholderDelimiters?.end.trim()) {\n throw new Error(\"Both start and end delimiters must be non-empty strings.\");\n }\n\n const { start, end } = placeholderDelimiters;\n\n // Create compile-path context for stringifying patch children\n const patchCtx = createPatchContext(file, hyperlinkSink);\n currentPatchCtx = patchCtx;\n\n for (const [patchKey, patchValue] of Object.entries(patches)) {\n const patchText = `${start}${patchKey}${end}`;\n while (true) {\n const { didFindOccurrence } = docxReplacer({\n context,\n json,\n keepOriginalStyles,\n patch: patchValue,\n patchText,\n });\n if (!recursive || !didFindOccurrence) {\n break;\n }\n }\n }\n\n // Flush hyperlink relationships captured by the compile-path context\n for (const hl of hyperlinkSink) {\n hyperlinkRelationshipAdditions.push({\n hyperlink: { id: hl.id, link: hl.link },\n key,\n });\n }\n\n const mediaDatas = getReferencedMedia(JSON.stringify(json), media.array);\n if (mediaDatas.length > 0) {\n hasMedia = true;\n imageRelationshipAdditions.push({\n key,\n mediaDatas,\n });\n }\n }\n\n map.set(key, json);\n }\n\n for (const { key, mediaDatas } of imageRelationshipAdditions) {\n const relationshipKey = `word/_rels/${key.split(\"/\").pop()}.rels`;\n const relationshipsJson = map.get(relationshipKey) ?? createRelationshipFile();\n map.set(relationshipKey, relationshipsJson);\n\n const index = getNextRelationshipIndex(relationshipsJson);\n const newJson = replaceImagePlaceholders(\n JSON.stringify(map.get(key)),\n mediaDatas,\n index,\n \"plain\",\n );\n map.set(key, JSON.parse(newJson) as Element);\n\n for (let i = 0; i < mediaDatas.length; i++) {\n const { fileName } = mediaDatas[i];\n appendRelationship(\n relationshipsJson,\n index + i,\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\",\n `media/${fileName}`,\n );\n }\n }\n\n for (const { key, hyperlink } of hyperlinkRelationshipAdditions) {\n const relationshipKey = `word/_rels/${key.split(\"/\").pop()}.rels`;\n\n const relationshipsJson = map.get(relationshipKey) ?? createRelationshipFile();\n map.set(relationshipKey, relationshipsJson);\n\n appendRelationship(\n relationshipsJson,\n hyperlink.id,\n \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\",\n hyperlink.link,\n TargetModeType.EXTERNAL,\n );\n }\n\n if (hasMedia) {\n const contentTypesJson = map.get(\"[Content_Types].xml\");\n\n if (!contentTypesJson) {\n throw new Error(\"Could not find content types file\");\n }\n\n appendContentType(contentTypesJson, \"image/png\", \"png\");\n appendContentType(contentTypesJson, \"image/jpeg\", \"jpeg\");\n appendContentType(contentTypesJson, \"image/jpeg\", \"jpg\");\n appendContentType(contentTypesJson, \"image/bmp\", \"bmp\");\n appendContentType(contentTypesJson, \"image/gif\", \"gif\");\n appendContentType(contentTypesJson, \"image/svg+xml\", \"svg\");\n }\n\n const files: Record<string, Uint8Array> = {};\n\n for (const [key, value] of map) {\n files[key] = encoder.encode(js2xml(value));\n }\n\n for (const [key, value] of binaryContentMap) {\n files[key] = value;\n }\n\n for (const { data: mediaData, fileName } of media.array) {\n files[`word/media/${fileName}`] =\n mediaData instanceof Uint8Array ? mediaData : new Uint8Array(mediaData);\n }\n\n return await zipAndConvert(files, outputType, OoxmlMimeType.DOCX);\n};\n\nconst createRelationshipFile = (): Element => ({\n declaration: {\n attributes: {\n encoding: \"UTF-8\",\n standalone: \"yes\",\n version: \"1.0\",\n },\n },\n elements: [\n {\n attributes: {\n xmlns: \"http://schemas.openxmlformats.org/package/2006/relationships\",\n },\n elements: [],\n name: \"Relationships\",\n type: \"element\",\n },\n ],\n});\n","/**\n * Patch detector for discovering placeholders in document templates.\n *\n * @module\n */\nimport { DOCX_NS, createTraverser, strFromU8, toJson, unzipSync } from \"@office-open/core\";\nimport { toUint8Array } from \"@office-open/core\";\n\nimport type { InputDataType } from \"./from-docx\";\n\n/**\n * Options for patch detection.\n *\n * @property data - The document template to scan for placeholders\n */\ninterface PatchDetectorOptions {\n data: InputDataType;\n}\n\n/**\n * Detects all placeholders present in a document template.\n *\n * Scans through all XML content in a .docx file to find placeholder text\n * enclosed in delimiters (default: {{placeholder}}). This is useful for\n * discovering what patches a template expects before performing replacement.\n *\n * @param options - Patch detector configuration\n * @returns Array of placeholder keys found in the document\n *\n * @example\n * ```typescript\n * const placeholders = await patchDetector({ data: templateBuffer });\n * // Returns: [\"name\", \"date\", \"address\"] if template contains {{name}}, {{date}}, {{address}}\n *\n * // Use detected placeholders to create patches\n * const patches = {};\n * for (const key of placeholders) {\n * patches[key] = {\n * type: PatchType.PARAGRAPH,\n * children: [new TextRun(getUserData(key))],\n * };\n * });\n * ```\n */\nexport const patchDetector = async ({ data }: PatchDetectorOptions): Promise<string[]> => {\n const zipContent = unzipSync(toUint8Array(data));\n const patches = new Set<string>();\n\n for (const [key, value] of Object.entries(zipContent)) {\n if (!key.endsWith(\".xml\") && !key.endsWith(\".rels\")) {\n continue;\n }\n if (key.startsWith(\"word/\") && !key.endsWith(\".xml.rels\")) {\n const json = toJson(strFromU8(value));\n const { traverse } = createTraverser(DOCX_NS);\n for (const p of traverse(json)) {\n for (const patch of findPatchKeys(p.text)) {\n patches.add(patch);\n }\n }\n }\n }\n return [...patches];\n};\n\n/**\n * Extracts placeholder keys from text using regex pattern.\n *\n * @param text - Text to search for placeholders\n * @returns Array of placeholder keys (without delimiters)\n */\nconst findPatchKeys = (text: string): string[] => {\n const pattern = /(?<=\\{\\{).+?(?=\\}\\})/gs;\n return text.match(pattern) ?? [];\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@office-open/docx",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "Generate, parse, and patch .docx documents with a declarative TypeScript API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"clippy",
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@office-open/core": "0.9.
|
|
57
|
-
"@office-open/xml": "0.9.
|
|
56
|
+
"@office-open/core": "0.9.3",
|
|
57
|
+
"@office-open/xml": "0.9.3"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
|
60
60
|
"dev": "basis build --stub",
|