@open-agreements/open-agreements 0.2.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/LICENSE +21 -0
- package/README.md +359 -0
- package/bin/open-agreements.js +4 -0
- package/content/external/LICENSE +27 -0
- package/content/external/README.md +38 -0
- package/content/external/yc-safe-discount/README.md +16 -0
- package/content/external/yc-safe-discount/clean.json +4 -0
- package/content/external/yc-safe-discount/metadata.yaml +67 -0
- package/content/external/yc-safe-discount/replacements.json +13 -0
- package/content/external/yc-safe-discount/template.docx +0 -0
- package/content/external/yc-safe-mfn/README.md +16 -0
- package/content/external/yc-safe-mfn/clean.json +4 -0
- package/content/external/yc-safe-mfn/metadata.yaml +64 -0
- package/content/external/yc-safe-mfn/replacements.json +12 -0
- package/content/external/yc-safe-mfn/template.docx +0 -0
- package/content/external/yc-safe-pro-rata-side-letter/README.md +16 -0
- package/content/external/yc-safe-pro-rata-side-letter/clean.json +4 -0
- package/content/external/yc-safe-pro-rata-side-letter/metadata.yaml +49 -0
- package/content/external/yc-safe-pro-rata-side-letter/replacements.json +9 -0
- package/content/external/yc-safe-pro-rata-side-letter/template.docx +0 -0
- package/content/external/yc-safe-valuation-cap/README.md +16 -0
- package/content/external/yc-safe-valuation-cap/clean.json +4 -0
- package/content/external/yc-safe-valuation-cap/metadata.yaml +64 -0
- package/content/external/yc-safe-valuation-cap/replacements.json +12 -0
- package/content/external/yc-safe-valuation-cap/template.docx +0 -0
- package/content/recipes/nvca-certificate-of-incorporation/clean.json +8 -0
- package/content/recipes/nvca-certificate-of-incorporation/metadata.yaml +43 -0
- package/content/recipes/nvca-certificate-of-incorporation/replacements.json +9 -0
- package/content/recipes/nvca-indemnification-agreement/clean.json +17 -0
- package/content/recipes/nvca-indemnification-agreement/metadata.yaml +79 -0
- package/content/recipes/nvca-indemnification-agreement/replacements.json +17 -0
- package/content/recipes/nvca-investors-rights-agreement/clean.json +12 -0
- package/content/recipes/nvca-investors-rights-agreement/metadata.yaml +71 -0
- package/content/recipes/nvca-investors-rights-agreement/replacements.json +18 -0
- package/content/recipes/nvca-management-rights-letter/clean.json +7 -0
- package/content/recipes/nvca-management-rights-letter/metadata.yaml +47 -0
- package/content/recipes/nvca-management-rights-letter/replacements.json +11 -0
- package/content/recipes/nvca-rofr-co-sale-agreement/clean.json +7 -0
- package/content/recipes/nvca-rofr-co-sale-agreement/metadata.yaml +76 -0
- package/content/recipes/nvca-rofr-co-sale-agreement/replacements.json +17 -0
- package/content/recipes/nvca-stock-purchase-agreement/clean.json +13 -0
- package/content/recipes/nvca-stock-purchase-agreement/computed.json +103 -0
- package/content/recipes/nvca-stock-purchase-agreement/metadata.yaml +138 -0
- package/content/recipes/nvca-stock-purchase-agreement/normalize.json +83 -0
- package/content/recipes/nvca-stock-purchase-agreement/replacements.json +41 -0
- package/content/recipes/nvca-voting-agreement/README.md +53 -0
- package/content/recipes/nvca-voting-agreement/clean.json +7 -0
- package/content/recipes/nvca-voting-agreement/metadata.yaml +66 -0
- package/content/recipes/nvca-voting-agreement/replacements.json +18 -0
- package/content/templates/bonterms-mutual-nda/README.md +27 -0
- package/content/templates/bonterms-mutual-nda/metadata.yaml +58 -0
- package/content/templates/bonterms-mutual-nda/source.json +18 -0
- package/content/templates/bonterms-mutual-nda/template.docx +0 -0
- package/content/templates/bonterms-professional-services-agreement/README.md +24 -0
- package/content/templates/bonterms-professional-services-agreement/metadata.yaml +45 -0
- package/content/templates/bonterms-professional-services-agreement/selections.json +12 -0
- package/content/templates/bonterms-professional-services-agreement/source.json +18 -0
- package/content/templates/bonterms-professional-services-agreement/template.docx +0 -0
- package/content/templates/closing-checklist/metadata.yaml +39 -0
- package/content/templates/closing-checklist/template.docx +0 -0
- package/content/templates/common-paper-ai-addendum/README.md +23 -0
- package/content/templates/common-paper-ai-addendum/metadata.yaml +31 -0
- package/content/templates/common-paper-ai-addendum/template.docx +0 -0
- package/content/templates/common-paper-ai-addendum-in-app/README.md +21 -0
- package/content/templates/common-paper-ai-addendum-in-app/metadata.yaml +21 -0
- package/content/templates/common-paper-ai-addendum-in-app/template.docx +0 -0
- package/content/templates/common-paper-amendment/README.md +27 -0
- package/content/templates/common-paper-amendment/metadata.yaml +53 -0
- package/content/templates/common-paper-amendment/template.docx +0 -0
- package/content/templates/common-paper-business-associate-agreement/README.md +29 -0
- package/content/templates/common-paper-business-associate-agreement/metadata.yaml +56 -0
- package/content/templates/common-paper-business-associate-agreement/replacements.json +3 -0
- package/content/templates/common-paper-business-associate-agreement/template.docx +0 -0
- package/content/templates/common-paper-cloud-service-agreement/README.md +32 -0
- package/content/templates/common-paper-cloud-service-agreement/metadata.yaml +354 -0
- package/content/templates/common-paper-cloud-service-agreement/template.docx +0 -0
- package/content/templates/common-paper-csa-click-through/README.md +33 -0
- package/content/templates/common-paper-csa-click-through/metadata.yaml +73 -0
- package/content/templates/common-paper-csa-click-through/template.docx +0 -0
- package/content/templates/common-paper-csa-with-ai/README.md +49 -0
- package/content/templates/common-paper-csa-with-ai/metadata.yaml +143 -0
- package/content/templates/common-paper-csa-with-ai/replacements.json +7 -0
- package/content/templates/common-paper-csa-with-ai/template.docx +0 -0
- package/content/templates/common-paper-csa-with-sla/README.md +53 -0
- package/content/templates/common-paper-csa-with-sla/metadata.yaml +159 -0
- package/content/templates/common-paper-csa-with-sla/replacements.json +7 -0
- package/content/templates/common-paper-csa-with-sla/template.docx +0 -0
- package/content/templates/common-paper-csa-without-sla/README.md +47 -0
- package/content/templates/common-paper-csa-without-sla/metadata.yaml +135 -0
- package/content/templates/common-paper-csa-without-sla/replacements.json +7 -0
- package/content/templates/common-paper-csa-without-sla/template.docx +0 -0
- package/content/templates/common-paper-data-processing-agreement/README.md +46 -0
- package/content/templates/common-paper-data-processing-agreement/metadata.yaml +130 -0
- package/content/templates/common-paper-data-processing-agreement/replacements.json +3 -0
- package/content/templates/common-paper-data-processing-agreement/template.docx +0 -0
- package/content/templates/common-paper-design-partner-agreement/README.md +29 -0
- package/content/templates/common-paper-design-partner-agreement/metadata.yaml +59 -0
- package/content/templates/common-paper-design-partner-agreement/replacements.json +4 -0
- package/content/templates/common-paper-design-partner-agreement/template.docx +0 -0
- package/content/templates/common-paper-independent-contractor-agreement/README.md +27 -0
- package/content/templates/common-paper-independent-contractor-agreement/metadata.yaml +55 -0
- package/content/templates/common-paper-independent-contractor-agreement/template.docx +0 -0
- package/content/templates/common-paper-letter-of-intent/README.md +25 -0
- package/content/templates/common-paper-letter-of-intent/metadata.yaml +42 -0
- package/content/templates/common-paper-letter-of-intent/template.docx +0 -0
- package/content/templates/common-paper-mutual-nda/README.md +29 -0
- package/content/templates/common-paper-mutual-nda/metadata.yaml +59 -0
- package/content/templates/common-paper-mutual-nda/selections.json +38 -0
- package/content/templates/common-paper-mutual-nda/template.docx +0 -0
- package/content/templates/common-paper-one-way-nda/README.md +27 -0
- package/content/templates/common-paper-one-way-nda/metadata.yaml +59 -0
- package/content/templates/common-paper-one-way-nda/template.docx +0 -0
- package/content/templates/common-paper-order-form/README.md +36 -0
- package/content/templates/common-paper-order-form/metadata.yaml +87 -0
- package/content/templates/common-paper-order-form/replacements.json +5 -0
- package/content/templates/common-paper-order-form/template.docx +0 -0
- package/content/templates/common-paper-order-form-with-sla/README.md +42 -0
- package/content/templates/common-paper-order-form-with-sla/metadata.yaml +111 -0
- package/content/templates/common-paper-order-form-with-sla/replacements.json +5 -0
- package/content/templates/common-paper-order-form-with-sla/template.docx +0 -0
- package/content/templates/common-paper-partnership-agreement/README.md +34 -0
- package/content/templates/common-paper-partnership-agreement/metadata.yaml +78 -0
- package/content/templates/common-paper-partnership-agreement/replacements.json +7 -0
- package/content/templates/common-paper-partnership-agreement/template.docx +0 -0
- package/content/templates/common-paper-pilot-agreement/README.md +34 -0
- package/content/templates/common-paper-pilot-agreement/metadata.yaml +100 -0
- package/content/templates/common-paper-pilot-agreement/replacements.json +4 -0
- package/content/templates/common-paper-pilot-agreement/selections.json +37 -0
- package/content/templates/common-paper-pilot-agreement/template.docx +0 -0
- package/content/templates/common-paper-professional-services-agreement/README.md +44 -0
- package/content/templates/common-paper-professional-services-agreement/metadata.yaml +124 -0
- package/content/templates/common-paper-professional-services-agreement/replacements.json +8 -0
- package/content/templates/common-paper-professional-services-agreement/template.docx +0 -0
- package/content/templates/common-paper-software-license-agreement/README.md +18 -0
- package/content/templates/common-paper-software-license-agreement/metadata.yaml +13 -0
- package/content/templates/common-paper-software-license-agreement/template.docx +0 -0
- package/content/templates/common-paper-statement-of-work/README.md +32 -0
- package/content/templates/common-paper-statement-of-work/metadata.yaml +71 -0
- package/content/templates/common-paper-statement-of-work/replacements.json +3 -0
- package/content/templates/common-paper-statement-of-work/template.docx +0 -0
- package/content/templates/common-paper-term-sheet/README.md +22 -0
- package/content/templates/common-paper-term-sheet/metadata.yaml +28 -0
- package/content/templates/common-paper-term-sheet/template.docx +0 -0
- package/content/templates/openagreements-employee-ip-inventions-assignment/README.md +31 -0
- package/content/templates/openagreements-employee-ip-inventions-assignment/metadata.yaml +71 -0
- package/content/templates/openagreements-employee-ip-inventions-assignment/template.docx +0 -0
- package/content/templates/openagreements-employee-ip-inventions-assignment/template.md +80 -0
- package/content/templates/openagreements-employment-confidentiality-acknowledgement/README.md +30 -0
- package/content/templates/openagreements-employment-confidentiality-acknowledgement/metadata.yaml +60 -0
- package/content/templates/openagreements-employment-confidentiality-acknowledgement/template.docx +0 -0
- package/content/templates/openagreements-employment-confidentiality-acknowledgement/template.md +51 -0
- package/content/templates/openagreements-employment-offer-letter/README.md +33 -0
- package/content/templates/openagreements-employment-offer-letter/metadata.yaml +75 -0
- package/content/templates/openagreements-employment-offer-letter/template.docx +0 -0
- package/content/templates/openagreements-employment-offer-letter/template.md +90 -0
- package/content/templates/working-group-list/metadata.yaml +22 -0
- package/content/templates/working-group-list/template.docx +0 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +199 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/checklist.d.ts +22 -0
- package/dist/commands/checklist.d.ts.map +1 -0
- package/dist/commands/checklist.js +222 -0
- package/dist/commands/checklist.js.map +1 -0
- package/dist/commands/fill.d.ts +18 -0
- package/dist/commands/fill.d.ts.map +1 -0
- package/dist/commands/fill.js +119 -0
- package/dist/commands/fill.js.map +1 -0
- package/dist/commands/list.d.ts +7 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +247 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/recipe.d.ts +24 -0
- package/dist/commands/recipe.d.ts.map +1 -0
- package/dist/commands/recipe.js +96 -0
- package/dist/commands/recipe.js.map +1 -0
- package/dist/commands/scan.d.ts +28 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +138 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/validate.d.ts +6 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +158 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/core/checklist/index.d.ts +38 -0
- package/dist/core/checklist/index.d.ts.map +1 -0
- package/dist/core/checklist/index.js +229 -0
- package/dist/core/checklist/index.js.map +1 -0
- package/dist/core/checklist/patch-apply.d.ts +65 -0
- package/dist/core/checklist/patch-apply.d.ts.map +1 -0
- package/dist/core/checklist/patch-apply.js +274 -0
- package/dist/core/checklist/patch-apply.js.map +1 -0
- package/dist/core/checklist/patch-schemas.d.ts +86 -0
- package/dist/core/checklist/patch-schemas.d.ts.map +1 -0
- package/dist/core/checklist/patch-schemas.js +89 -0
- package/dist/core/checklist/patch-schemas.js.map +1 -0
- package/dist/core/checklist/patch-validator.d.ts +76 -0
- package/dist/core/checklist/patch-validator.d.ts.map +1 -0
- package/dist/core/checklist/patch-validator.js +404 -0
- package/dist/core/checklist/patch-validator.js.map +1 -0
- package/dist/core/checklist/schemas.d.ts +270 -0
- package/dist/core/checklist/schemas.d.ts.map +1 -0
- package/dist/core/checklist/schemas.js +229 -0
- package/dist/core/checklist/schemas.js.map +1 -0
- package/dist/core/checklist/test-utils.d.ts +7 -0
- package/dist/core/checklist/test-utils.d.ts.map +1 -0
- package/dist/core/checklist/test-utils.js +13 -0
- package/dist/core/checklist/test-utils.js.map +1 -0
- package/dist/core/command-generation/adapters/claude.d.ts +11 -0
- package/dist/core/command-generation/adapters/claude.d.ts.map +1 -0
- package/dist/core/command-generation/adapters/claude.js +91 -0
- package/dist/core/command-generation/adapters/claude.js.map +1 -0
- package/dist/core/command-generation/types.d.ts +14 -0
- package/dist/core/command-generation/types.d.ts.map +1 -0
- package/dist/core/command-generation/types.js +2 -0
- package/dist/core/command-generation/types.js.map +1 -0
- package/dist/core/employment/jurisdiction-rules.d.ts +20 -0
- package/dist/core/employment/jurisdiction-rules.d.ts.map +1 -0
- package/dist/core/employment/jurisdiction-rules.js +57 -0
- package/dist/core/employment/jurisdiction-rules.js.map +1 -0
- package/dist/core/employment/memo.d.ts +57 -0
- package/dist/core/employment/memo.d.ts.map +1 -0
- package/dist/core/employment/memo.js +589 -0
- package/dist/core/employment/memo.js.map +1 -0
- package/dist/core/engine.d.ts +13 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +182 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/external/index.d.ts +8 -0
- package/dist/core/external/index.d.ts.map +1 -0
- package/dist/core/external/index.js +50 -0
- package/dist/core/external/index.js.map +1 -0
- package/dist/core/external/types.d.ts +18 -0
- package/dist/core/external/types.d.ts.map +1 -0
- package/dist/core/external/types.js +2 -0
- package/dist/core/external/types.js.map +1 -0
- package/dist/core/fill-pipeline.d.ts +64 -0
- package/dist/core/fill-pipeline.d.ts.map +1 -0
- package/dist/core/fill-pipeline.js +350 -0
- package/dist/core/fill-pipeline.js.map +1 -0
- package/dist/core/fill-utils.d.ts +39 -0
- package/dist/core/fill-utils.d.ts.map +1 -0
- package/dist/core/fill-utils.js +127 -0
- package/dist/core/fill-utils.js.map +1 -0
- package/dist/core/metadata.d.ts +194 -0
- package/dist/core/metadata.d.ts.map +1 -0
- package/dist/core/metadata.js +197 -0
- package/dist/core/metadata.js.map +1 -0
- package/dist/core/recipe/bracket-normalizer.d.ts +46 -0
- package/dist/core/recipe/bracket-normalizer.d.ts.map +1 -0
- package/dist/core/recipe/bracket-normalizer.js +354 -0
- package/dist/core/recipe/bracket-normalizer.js.map +1 -0
- package/dist/core/recipe/cleaner.d.ts +27 -0
- package/dist/core/recipe/cleaner.d.ts.map +1 -0
- package/dist/core/recipe/cleaner.js +345 -0
- package/dist/core/recipe/cleaner.js.map +1 -0
- package/dist/core/recipe/computed.d.ts +136 -0
- package/dist/core/recipe/computed.d.ts.map +1 -0
- package/dist/core/recipe/computed.js +225 -0
- package/dist/core/recipe/computed.js.map +1 -0
- package/dist/core/recipe/downloader.d.ts +8 -0
- package/dist/core/recipe/downloader.d.ts.map +1 -0
- package/dist/core/recipe/downloader.js +58 -0
- package/dist/core/recipe/downloader.js.map +1 -0
- package/dist/core/recipe/index.d.ts +17 -0
- package/dist/core/recipe/index.d.ts.map +1 -0
- package/dist/core/recipe/index.js +90 -0
- package/dist/core/recipe/index.js.map +1 -0
- package/dist/core/recipe/ooxml-parts.d.ts +21 -0
- package/dist/core/recipe/ooxml-parts.d.ts.map +1 -0
- package/dist/core/recipe/ooxml-parts.js +33 -0
- package/dist/core/recipe/ooxml-parts.js.map +1 -0
- package/dist/core/recipe/patcher.d.ts +34 -0
- package/dist/core/recipe/patcher.d.ts.map +1 -0
- package/dist/core/recipe/patcher.js +423 -0
- package/dist/core/recipe/patcher.js.map +1 -0
- package/dist/core/recipe/replacement-keys.d.ts +33 -0
- package/dist/core/recipe/replacement-keys.d.ts.map +1 -0
- package/dist/core/recipe/replacement-keys.js +53 -0
- package/dist/core/recipe/replacement-keys.js.map +1 -0
- package/dist/core/recipe/source-drift.d.ts +33 -0
- package/dist/core/recipe/source-drift.d.ts.map +1 -0
- package/dist/core/recipe/source-drift.js +113 -0
- package/dist/core/recipe/source-drift.js.map +1 -0
- package/dist/core/recipe/types.d.ts +33 -0
- package/dist/core/recipe/types.d.ts.map +1 -0
- package/dist/core/recipe/types.js +2 -0
- package/dist/core/recipe/types.js.map +1 -0
- package/dist/core/recipe/verifier.d.ts +24 -0
- package/dist/core/recipe/verifier.d.ts.map +1 -0
- package/dist/core/recipe/verifier.js +158 -0
- package/dist/core/recipe/verifier.js.map +1 -0
- package/dist/core/selector.d.ts +41 -0
- package/dist/core/selector.d.ts.map +1 -0
- package/dist/core/selector.js +323 -0
- package/dist/core/selector.js.map +1 -0
- package/dist/core/unified-pipeline.d.ts +53 -0
- package/dist/core/unified-pipeline.d.ts.map +1 -0
- package/dist/core/unified-pipeline.js +107 -0
- package/dist/core/unified-pipeline.js.map +1 -0
- package/dist/core/validation/external.d.ts +16 -0
- package/dist/core/validation/external.d.ts.map +1 -0
- package/dist/core/validation/external.js +114 -0
- package/dist/core/validation/external.js.map +1 -0
- package/dist/core/validation/license.d.ts +15 -0
- package/dist/core/validation/license.d.ts.map +1 -0
- package/dist/core/validation/license.js +30 -0
- package/dist/core/validation/license.js.map +1 -0
- package/dist/core/validation/output.d.ts +12 -0
- package/dist/core/validation/output.d.ts.map +1 -0
- package/dist/core/validation/output.js +47 -0
- package/dist/core/validation/output.js.map +1 -0
- package/dist/core/validation/recipe.d.ts +19 -0
- package/dist/core/validation/recipe.d.ts.map +1 -0
- package/dist/core/validation/recipe.js +159 -0
- package/dist/core/validation/recipe.js.map +1 -0
- package/dist/core/validation/scan-metadata.d.ts +21 -0
- package/dist/core/validation/scan-metadata.d.ts.map +1 -0
- package/dist/core/validation/scan-metadata.js +70 -0
- package/dist/core/validation/scan-metadata.js.map +1 -0
- package/dist/core/validation/template.d.ts +11 -0
- package/dist/core/validation/template.d.ts.map +1 -0
- package/dist/core/validation/template.js +248 -0
- package/dist/core/validation/template.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/paths.d.ts +43 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +149 -0
- package/dist/utils/paths.js.map +1 -0
- package/package.json +148 -0
- package/skills/cloud-service-agreement/CONNECTORS.md +19 -0
- package/skills/cloud-service-agreement/SKILL.md +172 -0
- package/skills/data-privacy-agreement/CONNECTORS.md +19 -0
- package/skills/data-privacy-agreement/SKILL.md +158 -0
- package/skills/delaware-franchise-tax/CONNECTORS.md +16 -0
- package/skills/delaware-franchise-tax/SKILL.md +206 -0
- package/skills/delaware-franchise-tax/reference/ecorp-portal-playwright-notes.md +136 -0
- package/skills/delaware-franchise-tax/reference/faq.md +101 -0
- package/skills/delaware-franchise-tax/reference/filing-instructions.md +111 -0
- package/skills/delaware-franchise-tax/reference/tax-calculation.md +167 -0
- package/skills/employment-contract/CONNECTORS.md +19 -0
- package/skills/employment-contract/SKILL.md +157 -0
- package/skills/nda/CONNECTORS.md +19 -0
- package/skills/nda/SKILL.md +153 -0
- package/skills/open-agreements/CONNECTORS.md +19 -0
- package/skills/open-agreements/SKILL.md +182 -0
- package/skills/safe/CONNECTORS.md +19 -0
- package/skills/safe/SKILL.md +161 -0
- package/skills/services-agreement/CONNECTORS.md +19 -0
- package/skills/services-agreement/SKILL.md +156 -0
- package/skills/unit-test-philosophy/SKILL.md +113 -0
- package/skills/unit-test-philosophy/references/allure-test-spec-writing-guide.md +164 -0
- package/skills/venture-financing/CONNECTORS.md +19 -0
- package/skills/venture-financing/SKILL.md +169 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared fill pipeline used by all three fill paths (template, external, recipe).
|
|
3
|
+
* Centralizes: defaults, boolean coercion, display fields, currency sanitization,
|
|
4
|
+
* drafting note removal, and the docx-templates createReport() call.
|
|
5
|
+
*/
|
|
6
|
+
import AdmZip from 'adm-zip';
|
|
7
|
+
import { DOMParser, XMLSerializer } from '@xmldom/xmldom';
|
|
8
|
+
import { createReport } from 'docx-templates';
|
|
9
|
+
import { sanitizeCurrencyValuesFromDocx, BLANK_PLACEHOLDER } from './fill-utils.js';
|
|
10
|
+
import { enumerateTextParts, getGeneralTextPartNames } from './recipe/ooxml-parts.js';
|
|
11
|
+
const W_NS = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
12
|
+
/** Default patterns for paragraphs stripped before filling. */
|
|
13
|
+
const DEFAULT_STRIP_PATTERNS = [/\bDrafting note\b/i];
|
|
14
|
+
/**
|
|
15
|
+
* Prepare fill data with all normalization steps:
|
|
16
|
+
* 1. Validate required fields are present
|
|
17
|
+
* 2. Apply defaults for optional fields not provided
|
|
18
|
+
* 3. Coerce boolean fields (optional)
|
|
19
|
+
* 4. Compute display fields (optional, template-specific)
|
|
20
|
+
*/
|
|
21
|
+
export function prepareFillData(options) {
|
|
22
|
+
const { values, fields, requiredFieldNames = [], useBlankPlaceholder = false, coerceBooleans = false, computeDisplayFields, } = options;
|
|
23
|
+
// Apply defaults for fields not provided
|
|
24
|
+
const defaultValue = useBlankPlaceholder ? BLANK_PLACEHOLDER : '';
|
|
25
|
+
const data = { ...values };
|
|
26
|
+
for (const field of fields) {
|
|
27
|
+
if (!(field.name in data)) {
|
|
28
|
+
// Array fields default to empty array, not blank placeholder
|
|
29
|
+
if (field.type === 'array') {
|
|
30
|
+
data[field.name] = [];
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
data[field.name] = field.default ?? defaultValue;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Warn about required fields that are still unfilled (no value, no default)
|
|
38
|
+
const requiredSet = new Set(requiredFieldNames);
|
|
39
|
+
const missing = fields
|
|
40
|
+
.filter((f) => requiredSet.has(f.name) && (data[f.name] === '' || data[f.name] === BLANK_PLACEHOLDER))
|
|
41
|
+
.map((f) => f.name);
|
|
42
|
+
if (missing.length > 0) {
|
|
43
|
+
console.warn(`Warning: missing required fields: ${missing.join(', ')}`);
|
|
44
|
+
}
|
|
45
|
+
// Coerce boolean fields to actual JS booleans.
|
|
46
|
+
// docx-templates evaluates {IF field} in JS context where "false" is truthy.
|
|
47
|
+
if (coerceBooleans) {
|
|
48
|
+
for (const field of fields) {
|
|
49
|
+
if (field.type === 'boolean' && field.name in data) {
|
|
50
|
+
const v = data[field.name];
|
|
51
|
+
data[field.name] = v === true || v === 'true';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Compute display fields (template-specific: radio/checkbox groups)
|
|
56
|
+
if (computeDisplayFields) {
|
|
57
|
+
computeDisplayFields(data);
|
|
58
|
+
}
|
|
59
|
+
return data;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Extract paragraph text by concatenating all <w:t> elements.
|
|
63
|
+
*/
|
|
64
|
+
function extractParagraphText(para) {
|
|
65
|
+
if (!para.getElementsByTagNameNS)
|
|
66
|
+
return '';
|
|
67
|
+
const tElements = para.getElementsByTagNameNS(W_NS, 't');
|
|
68
|
+
const parts = [];
|
|
69
|
+
for (let i = 0; i < tElements.length; i++) {
|
|
70
|
+
parts.push(tElements[i].textContent ?? '');
|
|
71
|
+
}
|
|
72
|
+
return parts.join('').trim();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check if a table row contains ONLY paragraphs that match the strip patterns
|
|
76
|
+
* (or are empty). If so, the entire row can be safely removed.
|
|
77
|
+
*/
|
|
78
|
+
function isRowOnlyDraftingNotes(tr, patterns) {
|
|
79
|
+
const paras = tr.getElementsByTagNameNS(W_NS, 'p');
|
|
80
|
+
if (paras.length === 0)
|
|
81
|
+
return false;
|
|
82
|
+
for (let i = 0; i < paras.length; i++) {
|
|
83
|
+
const text = extractParagraphText(paras[i]);
|
|
84
|
+
if (text === '')
|
|
85
|
+
continue; // empty paragraphs are fine to remove
|
|
86
|
+
if (!patterns.some((r) => r.test(text)))
|
|
87
|
+
return false; // non-matching content
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Remove paragraphs matching the given patterns from a DOCX buffer.
|
|
93
|
+
* If a matched paragraph is the sole content of a table row, the entire
|
|
94
|
+
* row is removed (avoids empty highlighted rows in Common Paper docs).
|
|
95
|
+
*
|
|
96
|
+
* Returns a new DOCX buffer with the paragraphs removed.
|
|
97
|
+
*/
|
|
98
|
+
function stripParagraphs(docxBuffer, patterns) {
|
|
99
|
+
if (patterns.length === 0)
|
|
100
|
+
return docxBuffer;
|
|
101
|
+
const zip = new AdmZip(docxBuffer);
|
|
102
|
+
const parser = new DOMParser();
|
|
103
|
+
const serializer = new XMLSerializer();
|
|
104
|
+
const parts = enumerateTextParts(zip);
|
|
105
|
+
const partNames = getGeneralTextPartNames(parts);
|
|
106
|
+
let modified = false;
|
|
107
|
+
for (const partName of partNames) {
|
|
108
|
+
const entry = zip.getEntry(partName);
|
|
109
|
+
if (!entry)
|
|
110
|
+
continue;
|
|
111
|
+
const xml = entry.getData().toString('utf-8');
|
|
112
|
+
const doc = parser.parseFromString(xml, 'text/xml');
|
|
113
|
+
// Collect table rows to remove (whole row when only drafting notes)
|
|
114
|
+
const rowsToRemove = new Set();
|
|
115
|
+
// Collect standalone paragraphs to remove
|
|
116
|
+
const parasToRemove = [];
|
|
117
|
+
const allParagraphs = doc.getElementsByTagNameNS(W_NS, 'p');
|
|
118
|
+
for (let i = 0; i < allParagraphs.length; i++) {
|
|
119
|
+
const para = allParagraphs[i];
|
|
120
|
+
const text = extractParagraphText(para);
|
|
121
|
+
if (!text || !patterns.some((r) => r.test(text)))
|
|
122
|
+
continue;
|
|
123
|
+
// Walk up to find if this is inside a table cell
|
|
124
|
+
let node = para.parentNode;
|
|
125
|
+
let inTableCell = false;
|
|
126
|
+
let tableRow = null;
|
|
127
|
+
while (node) {
|
|
128
|
+
if (node.nodeType === 1) {
|
|
129
|
+
const element = node;
|
|
130
|
+
if (element.localName === 'tc' && element.namespaceURI === W_NS) {
|
|
131
|
+
inTableCell = true;
|
|
132
|
+
}
|
|
133
|
+
if (element.localName === 'tr' && element.namespaceURI === W_NS) {
|
|
134
|
+
tableRow = element;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
node = node.parentNode;
|
|
139
|
+
}
|
|
140
|
+
if (inTableCell && tableRow && isRowOnlyDraftingNotes(tableRow, patterns)) {
|
|
141
|
+
rowsToRemove.add(tableRow);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
parasToRemove.push(para);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (rowsToRemove.size > 0 || parasToRemove.length > 0) {
|
|
148
|
+
modified = true;
|
|
149
|
+
for (const row of rowsToRemove) {
|
|
150
|
+
row.parentNode?.removeChild(row);
|
|
151
|
+
}
|
|
152
|
+
for (const para of parasToRemove) {
|
|
153
|
+
para.parentNode?.removeChild(para);
|
|
154
|
+
}
|
|
155
|
+
// Update the zip entry
|
|
156
|
+
const outXml = serializer.serializeToString(doc);
|
|
157
|
+
zip.updateFile(partName, Buffer.from(outXml, 'utf-8'));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (!modified)
|
|
161
|
+
return docxBuffer;
|
|
162
|
+
// Rebuild the zip from scratch (adm-zip data descriptor workaround)
|
|
163
|
+
const outZip = new AdmZip();
|
|
164
|
+
for (const entry of zip.getEntries()) {
|
|
165
|
+
outZip.addFile(entry.entryName, entry.getData());
|
|
166
|
+
}
|
|
167
|
+
return outZip.toBuffer();
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Extract all text from a run (<w:r>) by concatenating its <w:t> elements.
|
|
171
|
+
*/
|
|
172
|
+
function extractRunText(run) {
|
|
173
|
+
const tElements = run.getElementsByTagNameNS(W_NS, 't');
|
|
174
|
+
const parts = [];
|
|
175
|
+
for (let i = 0; i < tElements.length; i++) {
|
|
176
|
+
parts.push(tElements[i].textContent ?? '');
|
|
177
|
+
}
|
|
178
|
+
return parts.join('');
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Remove <w:highlight> elements only from runs whose template tags
|
|
182
|
+
* are being filled with non-empty values. Unfilled fields keep their
|
|
183
|
+
* yellow highlighting so users can see what still needs attention.
|
|
184
|
+
*
|
|
185
|
+
* Works by finding runs containing {field_name} tags, checking whether
|
|
186
|
+
* the corresponding field has a non-empty value in the data, and only
|
|
187
|
+
* stripping the highlight if it does.
|
|
188
|
+
*/
|
|
189
|
+
function stripFilledHighlighting(docxBuffer, filledFields) {
|
|
190
|
+
if (filledFields.size === 0)
|
|
191
|
+
return docxBuffer;
|
|
192
|
+
const zip = new AdmZip(docxBuffer);
|
|
193
|
+
const parser = new DOMParser();
|
|
194
|
+
const serializer = new XMLSerializer();
|
|
195
|
+
const parts = enumerateTextParts(zip);
|
|
196
|
+
const partNames = getGeneralTextPartNames(parts);
|
|
197
|
+
// Match {field_name} but not {IF ...} or {END-IF ...} etc.
|
|
198
|
+
const tagPattern = /\{(\w+)\}/g;
|
|
199
|
+
let modified = false;
|
|
200
|
+
for (const partName of partNames) {
|
|
201
|
+
const entry = zip.getEntry(partName);
|
|
202
|
+
if (!entry)
|
|
203
|
+
continue;
|
|
204
|
+
const xml = entry.getData().toString('utf-8');
|
|
205
|
+
const doc = parser.parseFromString(xml, 'text/xml');
|
|
206
|
+
const allRuns = doc.getElementsByTagNameNS(W_NS, 'r');
|
|
207
|
+
const toRemove = [];
|
|
208
|
+
for (let i = 0; i < allRuns.length; i++) {
|
|
209
|
+
const run = allRuns[i];
|
|
210
|
+
const rPr = run.getElementsByTagNameNS(W_NS, 'rPr');
|
|
211
|
+
if (rPr.length === 0)
|
|
212
|
+
continue;
|
|
213
|
+
const highlights = rPr[0].getElementsByTagNameNS(W_NS, 'highlight');
|
|
214
|
+
if (highlights.length === 0)
|
|
215
|
+
continue;
|
|
216
|
+
// Check if this run's text contains a tag for a filled field
|
|
217
|
+
const runText = extractRunText(run);
|
|
218
|
+
let hasFilled = false;
|
|
219
|
+
let match = null;
|
|
220
|
+
tagPattern.lastIndex = 0;
|
|
221
|
+
while ((match = tagPattern.exec(runText)) !== null) {
|
|
222
|
+
if (filledFields.has(match[1])) {
|
|
223
|
+
hasFilled = true;
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (hasFilled) {
|
|
228
|
+
for (let j = 0; j < highlights.length; j++) {
|
|
229
|
+
toRemove.push(highlights[j]);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (toRemove.length > 0) {
|
|
234
|
+
modified = true;
|
|
235
|
+
for (const el of toRemove) {
|
|
236
|
+
el.parentNode?.removeChild(el);
|
|
237
|
+
}
|
|
238
|
+
const outXml = serializer.serializeToString(doc);
|
|
239
|
+
zip.updateFile(partName, Buffer.from(outXml, 'utf-8'));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (!modified)
|
|
243
|
+
return docxBuffer;
|
|
244
|
+
const outZip = new AdmZip();
|
|
245
|
+
for (const entry of zip.getEntries()) {
|
|
246
|
+
outZip.addFile(entry.entryName, entry.getData());
|
|
247
|
+
}
|
|
248
|
+
return outZip.toBuffer();
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Remove malformed/empty table rows that can be produced by conditional tags
|
|
252
|
+
* (for example false {IF ...} blocks wrapped around full row content).
|
|
253
|
+
*
|
|
254
|
+
* Some viewers (notably Apple Pages) may render entire tables incorrectly when
|
|
255
|
+
* a <w:tr> remains with <w:trPr> but no <w:tc> cells.
|
|
256
|
+
*/
|
|
257
|
+
function stripEmptyTableRows(docxBuffer) {
|
|
258
|
+
const zip = new AdmZip(docxBuffer);
|
|
259
|
+
const parser = new DOMParser();
|
|
260
|
+
const serializer = new XMLSerializer();
|
|
261
|
+
const parts = enumerateTextParts(zip);
|
|
262
|
+
const partNames = getGeneralTextPartNames(parts);
|
|
263
|
+
let modified = false;
|
|
264
|
+
for (const partName of partNames) {
|
|
265
|
+
const entry = zip.getEntry(partName);
|
|
266
|
+
if (!entry)
|
|
267
|
+
continue;
|
|
268
|
+
const xml = entry.getData().toString('utf-8');
|
|
269
|
+
const doc = parser.parseFromString(xml, 'text/xml');
|
|
270
|
+
const rows = doc.getElementsByTagNameNS(W_NS, 'tr');
|
|
271
|
+
const rowsToRemove = [];
|
|
272
|
+
for (let i = 0; i < rows.length; i++) {
|
|
273
|
+
const row = rows[i];
|
|
274
|
+
let hasCell = false;
|
|
275
|
+
for (let c = 0; c < row.childNodes.length; c++) {
|
|
276
|
+
const child = row.childNodes[c];
|
|
277
|
+
if (child?.nodeType === 1) {
|
|
278
|
+
const childElement = child;
|
|
279
|
+
if (childElement.localName === 'tc' && childElement.namespaceURI === W_NS) {
|
|
280
|
+
hasCell = true;
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (!hasCell) {
|
|
286
|
+
rowsToRemove.push(row);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (rowsToRemove.length > 0) {
|
|
290
|
+
modified = true;
|
|
291
|
+
for (const row of rowsToRemove) {
|
|
292
|
+
row.parentNode?.removeChild(row);
|
|
293
|
+
}
|
|
294
|
+
const outXml = serializer.serializeToString(doc);
|
|
295
|
+
zip.updateFile(partName, Buffer.from(outXml, 'utf-8'));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (!modified)
|
|
299
|
+
return docxBuffer;
|
|
300
|
+
const outZip = new AdmZip();
|
|
301
|
+
for (const entry of zip.getEntries()) {
|
|
302
|
+
outZip.addFile(entry.entryName, entry.getData());
|
|
303
|
+
}
|
|
304
|
+
return outZip.toBuffer();
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Fill a DOCX template with prepared data:
|
|
308
|
+
* 1. Strip drafting note paragraphs (configurable, on by default)
|
|
309
|
+
* 2. Strip highlighting from runs with filled fields (unfilled keep their highlight)
|
|
310
|
+
* 3. Sanitize currency values by scanning the template buffer for ${field} patterns
|
|
311
|
+
* 4. Call docx-templates createReport() with standard delimiters
|
|
312
|
+
* 5. Remove structurally empty table rows left by conditional rendering
|
|
313
|
+
* 6. Return the filled buffer
|
|
314
|
+
*/
|
|
315
|
+
export async function fillDocx(options) {
|
|
316
|
+
const { data, fixSmartQuotes = false, stripParagraphPatterns = DEFAULT_STRIP_PATTERNS, } = options;
|
|
317
|
+
let { templateBuffer } = options;
|
|
318
|
+
// Step 1: Strip drafting notes (and other configured patterns)
|
|
319
|
+
if (stripParagraphPatterns.length > 0) {
|
|
320
|
+
templateBuffer = stripParagraphs(templateBuffer, stripParagraphPatterns);
|
|
321
|
+
}
|
|
322
|
+
// Step 2: Strip highlighting only from fields that have non-empty values.
|
|
323
|
+
// Unfilled fields keep their yellow highlight as a visual cue.
|
|
324
|
+
const filledFields = new Set();
|
|
325
|
+
for (const [key, val] of Object.entries(data)) {
|
|
326
|
+
if (typeof val === 'string' && val !== '' && val !== BLANK_PLACEHOLDER) {
|
|
327
|
+
filledFields.add(key);
|
|
328
|
+
}
|
|
329
|
+
else if (typeof val === 'boolean') {
|
|
330
|
+
filledFields.add(key); // booleans are always "filled"
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
templateBuffer = stripFilledHighlighting(templateBuffer, filledFields);
|
|
334
|
+
// Step 3: Strip leading $ from values where the template has ${ before the tag
|
|
335
|
+
const sanitizedData = sanitizeCurrencyValuesFromDocx(data, templateBuffer);
|
|
336
|
+
// Step 4: Fill template
|
|
337
|
+
const filled = await createReport({
|
|
338
|
+
template: templateBuffer,
|
|
339
|
+
data: sanitizedData,
|
|
340
|
+
cmdDelimiter: ['{', '}'],
|
|
341
|
+
fixSmartQuotes,
|
|
342
|
+
// Emit line breaks as separate text runs for viewer compatibility.
|
|
343
|
+
processLineBreaks: true,
|
|
344
|
+
processLineBreaksAsNewText: true,
|
|
345
|
+
});
|
|
346
|
+
// Step 5: Remove malformed empty table rows from conditional rendering
|
|
347
|
+
const cleaned = stripEmptyTableRows(Buffer.from(filled));
|
|
348
|
+
return cleaned;
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=fill-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill-pipeline.js","sourceRoot":"","sources":["../../src/core/fill-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for the fill stage of all pipelines (template, recipe, external).
|
|
3
|
+
*/
|
|
4
|
+
import type { VerifyResult } from './recipe/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Visible placeholder rendered for fields the user hasn't filled yet.
|
|
7
|
+
* Makes it obvious what still needs attention in the output document.
|
|
8
|
+
*/
|
|
9
|
+
export declare const BLANK_PLACEHOLDER = "_______";
|
|
10
|
+
/**
|
|
11
|
+
* Scan a DOCX template buffer for fields that have a literal `$` immediately
|
|
12
|
+
* before the `{field_name}` tag. Returns the set of field names.
|
|
13
|
+
*
|
|
14
|
+
* Works by parsing OOXML text parts and concatenating `<w:t>` elements per
|
|
15
|
+
* paragraph, then matching `$` + `{field_name}` patterns. Handles cross-run
|
|
16
|
+
* splits because text is concatenated at the paragraph level.
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectCurrencyFields(docxBuffer: Buffer): Set<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Strip leading `$` from user values where the DOCX template already has
|
|
21
|
+
* a literal `$` before the `{field_name}` tag. Prevents double-dollar
|
|
22
|
+
* output like `$$1,000,000`.
|
|
23
|
+
*
|
|
24
|
+
* This is the DOCX-aware version that works for all pipelines — it scans
|
|
25
|
+
* the template buffer directly instead of requiring a replacements map.
|
|
26
|
+
*/
|
|
27
|
+
export declare function sanitizeCurrencyValuesFromDocx(values: Record<string, unknown>, docxBuffer: Buffer): Record<string, unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* Verify a filled template DOCX output.
|
|
30
|
+
* Runs a subset of checks that are safe for templates:
|
|
31
|
+
* - No double dollar signs (catches currency sanitization failures)
|
|
32
|
+
* - No unrendered {template_tags} (catches fill failures)
|
|
33
|
+
*
|
|
34
|
+
* Does NOT check: leftover brackets (templates don't use them),
|
|
35
|
+
* context values present (templates use {IF} conditionals that hide values),
|
|
36
|
+
* drafting notes (stripped by fillDocx), footnotes (may be legitimate).
|
|
37
|
+
*/
|
|
38
|
+
export declare function verifyTemplateFill(outputPath: string): VerifyResult;
|
|
39
|
+
//# sourceMappingURL=fill-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill-utils.d.ts","sourceRoot":"","sources":["../../src/core/fill-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA8BpE;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CAmDnE"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for the fill stage of all pipelines (template, recipe, external).
|
|
3
|
+
*/
|
|
4
|
+
import AdmZip from 'adm-zip';
|
|
5
|
+
import { DOMParser } from '@xmldom/xmldom';
|
|
6
|
+
import { enumerateTextParts, getGeneralTextPartNames } from './recipe/ooxml-parts.js';
|
|
7
|
+
const W_NS = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
8
|
+
/**
|
|
9
|
+
* Visible placeholder rendered for fields the user hasn't filled yet.
|
|
10
|
+
* Makes it obvious what still needs attention in the output document.
|
|
11
|
+
*/
|
|
12
|
+
export const BLANK_PLACEHOLDER = '_______';
|
|
13
|
+
/**
|
|
14
|
+
* Scan a DOCX template buffer for fields that have a literal `$` immediately
|
|
15
|
+
* before the `{field_name}` tag. Returns the set of field names.
|
|
16
|
+
*
|
|
17
|
+
* Works by parsing OOXML text parts and concatenating `<w:t>` elements per
|
|
18
|
+
* paragraph, then matching `$` + `{field_name}` patterns. Handles cross-run
|
|
19
|
+
* splits because text is concatenated at the paragraph level.
|
|
20
|
+
*/
|
|
21
|
+
export function detectCurrencyFields(docxBuffer) {
|
|
22
|
+
const zip = new AdmZip(docxBuffer);
|
|
23
|
+
const parser = new DOMParser();
|
|
24
|
+
const parts = enumerateTextParts(zip);
|
|
25
|
+
const partNames = getGeneralTextPartNames(parts);
|
|
26
|
+
const currencyFields = new Set();
|
|
27
|
+
for (const partName of partNames) {
|
|
28
|
+
const entry = zip.getEntry(partName);
|
|
29
|
+
if (!entry)
|
|
30
|
+
continue;
|
|
31
|
+
const xml = entry.getData().toString('utf-8');
|
|
32
|
+
const doc = parser.parseFromString(xml, 'text/xml');
|
|
33
|
+
const paras = doc.getElementsByTagNameNS(W_NS, 'p');
|
|
34
|
+
for (let i = 0; i < paras.length; i++) {
|
|
35
|
+
const tElements = paras[i].getElementsByTagNameNS(W_NS, 't');
|
|
36
|
+
let fullText = '';
|
|
37
|
+
for (let j = 0; j < tElements.length; j++) {
|
|
38
|
+
fullText += tElements[j].textContent ?? '';
|
|
39
|
+
}
|
|
40
|
+
const matches = fullText.matchAll(/\$\{(\w+)\}/g);
|
|
41
|
+
for (const m of matches) {
|
|
42
|
+
currencyFields.add(m[1]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return currencyFields;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Strip leading `$` from user values where the DOCX template already has
|
|
50
|
+
* a literal `$` before the `{field_name}` tag. Prevents double-dollar
|
|
51
|
+
* output like `$$1,000,000`.
|
|
52
|
+
*
|
|
53
|
+
* This is the DOCX-aware version that works for all pipelines — it scans
|
|
54
|
+
* the template buffer directly instead of requiring a replacements map.
|
|
55
|
+
*/
|
|
56
|
+
export function sanitizeCurrencyValuesFromDocx(values, docxBuffer) {
|
|
57
|
+
const currencyFields = detectCurrencyFields(docxBuffer);
|
|
58
|
+
if (currencyFields.size === 0)
|
|
59
|
+
return values;
|
|
60
|
+
const sanitized = { ...values };
|
|
61
|
+
for (const field of currencyFields) {
|
|
62
|
+
const v = sanitized[field];
|
|
63
|
+
if (typeof v === 'string' && v.startsWith('$')) {
|
|
64
|
+
sanitized[field] = v.slice(1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return sanitized;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Verify a filled template DOCX output.
|
|
71
|
+
* Runs a subset of checks that are safe for templates:
|
|
72
|
+
* - No double dollar signs (catches currency sanitization failures)
|
|
73
|
+
* - No unrendered {template_tags} (catches fill failures)
|
|
74
|
+
*
|
|
75
|
+
* Does NOT check: leftover brackets (templates don't use them),
|
|
76
|
+
* context values present (templates use {IF} conditionals that hide values),
|
|
77
|
+
* drafting notes (stripped by fillDocx), footnotes (may be legitimate).
|
|
78
|
+
*/
|
|
79
|
+
export function verifyTemplateFill(outputPath) {
|
|
80
|
+
const zip = new AdmZip(outputPath);
|
|
81
|
+
const parser = new DOMParser();
|
|
82
|
+
const parts = enumerateTextParts(zip);
|
|
83
|
+
const partNames = getGeneralTextPartNames(parts);
|
|
84
|
+
const allParagraphs = [];
|
|
85
|
+
for (const partName of partNames) {
|
|
86
|
+
const entry = zip.getEntry(partName);
|
|
87
|
+
if (!entry)
|
|
88
|
+
continue;
|
|
89
|
+
const xml = entry.getData().toString('utf-8');
|
|
90
|
+
const doc = parser.parseFromString(xml, 'text/xml');
|
|
91
|
+
const paras = doc.getElementsByTagNameNS(W_NS, 'p');
|
|
92
|
+
for (let i = 0; i < paras.length; i++) {
|
|
93
|
+
const tElements = paras[i].getElementsByTagNameNS(W_NS, 't');
|
|
94
|
+
const textParts = [];
|
|
95
|
+
for (let j = 0; j < tElements.length; j++) {
|
|
96
|
+
textParts.push(tElements[j].textContent ?? '');
|
|
97
|
+
}
|
|
98
|
+
if (textParts.length > 0) {
|
|
99
|
+
allParagraphs.push(textParts.join(''));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const rawFullText = allParagraphs.join('\n');
|
|
104
|
+
const checks = [];
|
|
105
|
+
// Check 1: No double dollar signs ($$ or $ $)
|
|
106
|
+
const doubleDollarPattern = /\$[\s\u00A0\t]*\$/;
|
|
107
|
+
const doubleDollarLines = rawFullText.split('\n').filter((line) => doubleDollarPattern.test(line));
|
|
108
|
+
checks.push({
|
|
109
|
+
name: 'No double dollar signs',
|
|
110
|
+
passed: doubleDollarLines.length === 0,
|
|
111
|
+
details: doubleDollarLines.length > 0
|
|
112
|
+
? `Found ${doubleDollarLines.length} occurrence(s): "${doubleDollarLines[0].trim().slice(0, 80)}"`
|
|
113
|
+
: undefined,
|
|
114
|
+
});
|
|
115
|
+
// Check 2: No unrendered {template_tags}
|
|
116
|
+
const unrenderedTags = rawFullText.match(/\{[a-z_][a-z0-9_]*\}/gi) ?? [];
|
|
117
|
+
checks.push({
|
|
118
|
+
name: 'No unrendered template tags',
|
|
119
|
+
passed: unrenderedTags.length === 0,
|
|
120
|
+
details: unrenderedTags.length > 0 ? `Found: ${unrenderedTags.join(', ')}` : undefined,
|
|
121
|
+
});
|
|
122
|
+
return {
|
|
123
|
+
passed: checks.every((c) => c.passed),
|
|
124
|
+
checks,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=fill-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill-utils.js","sourceRoot":"","sources":["../../src/core/fill-utils.ts"],"names":[],"mappings":"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"}
|