New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

docx-templates

Package Overview
Dependencies
Maintainers
1
Versions
63
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

docx-templates - npm Package Compare versions

Comparing version 4.0.0 to 4.1.0

.eslintignore

10

CHANGELOG.md

@@ -0,1 +1,11 @@

## 4.1.0 (2020-4-25)
## 4.1.0 (2020-04-23)
* #112 Failing on the first error that is encountered while rendering a template is now optional behaviour (but still the default). Use `failFast: false` to collect all errors in a template before failing. This allows for less cumbersome interactive correction of typos or other mistakes in template commands.
* #33 SVGs can now be inserted into the templates directly, based on excellent work by @lwallent.
* #113 fixed a regression caused by relying on incomplete jsZip type definitions.
* #83 fixed a bug that occurred when links were used in FOR loops.
* Added docstrings (thanks @mathe42 !)
## 4.0.0 (2020-04-13)

@@ -2,0 +12,0 @@

2

lib/jsSandbox.js

@@ -103,3 +103,3 @@ "use strict";

script = new vm_1.default.Script("\n __result__ = eval(__code__);\n ", {});
context = vm_1.default.createContext(sandbox); // eslint-disable-line new-cap
context = vm_1.default.createContext(sandbox);
script.runInContext(context);

@@ -106,0 +106,0 @@ result = context.__result__;

import { UserOptions, Node } from './types';
/**
* Create Report from docx template
*
* example:
* ```js
* createReport({
* template,
* data: query => graphqlServer.execute(query),
* additionalJsContext: {
* // all of these will be available to JS snippets in your template commands
* foo: 'bar',
* qrCode: async url => {
* // do stuff
* },
* },
* cmdDelimiter: '+++',
* literalXmlDelimiter: '||',
* processLineBreaks: true,
* noSandbox: false,
* });
* ```
*
* @param options Options for Report
*/
declare function createReport(options: UserOptions): Promise<Uint8Array>;
/**
* For development and testing purposes. Don't use _probe if you don't know what you are doing
*/
declare function createReport(options: UserOptions, _probe: 'JS'): Promise<Node>;
/**
* For development and testing purposes. Don't use _probe if you don't know what you are doing
*/
declare function createReport(options: UserOptions, _probe: 'XML'): Promise<string>;
export default createReport;

@@ -55,6 +55,6 @@ "use strict";

return __awaiter(this, void 0, void 0, function () {
var template, data, queryVars, templatePath, literalXmlDelimiter, createOptions, xmlOptions, zip, templateXml, tic, parseResult, jsTemplate, tac, finalTemplate, queryResult, query, result, report1, images1, links1, htmls1, reportXml, numImages, numHtmls, files, images, links, htmls, i, filePath, raw, js0, js, _a, report2, images2, links2, htmls2, xml, segments, documentComponent, contentTypesPath, contentTypesXml, contentTypes_1, ensureContentType, finalContentTypesXml, output;
var template, data, queryVars, templatePath, literalXmlDelimiter, createOptions, xmlOptions, zip, templateXml, tic, parseResult, jsTemplate, tac, finalTemplate, queryResult, query, result, report1, images1, links1, htmls1, reportXml, numImages, numHtmls, files, images, links, htmls, i, filePath, raw, js0, js, result_1, report2, images2, links2, htmls2, xml, segments, documentComponent, contentTypesPath, contentTypesXml, contentTypes_1, ensureContentType, finalContentTypesXml, output;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:

@@ -72,2 +72,3 @@ DEBUG && debug_1.default.debug('Report options:', { attach: options });

additionalJsContext: options.additionalJsContext || {},
failFast: options.failFast == null ? true : options.failFast,
};

@@ -81,3 +82,3 @@ xmlOptions = { literalXmlDelimiter: literalXmlDelimiter };

case 1:
zip = _b.sent();
zip = _a.sent();
// ---------------------------------------------------------

@@ -89,3 +90,3 @@ // Read the 'document.xml' file (the template) and parse it

case 2:
templateXml = _b.sent();
templateXml = _a.sent();
if (templateXml == null)

@@ -98,3 +99,3 @@ throw new Error('document.xml could not be found');

case 3:
parseResult = _b.sent();
parseResult = _a.sent();
jsTemplate = parseResult;

@@ -117,11 +118,11 @@ tac = new Date().getTime();

case 4:
query = _b.sent();
query = _a.sent();
DEBUG && debug_1.default.debug("Query: " + (query || 'no query found'));
return [4 /*yield*/, data(query, queryVars)];
case 5:
queryResult = _b.sent();
queryResult = _a.sent();
return [3 /*break*/, 7];
case 6:
queryResult = data;
_b.label = 7;
_a.label = 7;
case 7:

@@ -137,3 +138,6 @@ // ---------------------------------------------------------

case 8:
result = _b.sent();
result = _a.sent();
if (result.status === 'errors') {
throw result.errors;
}
report1 = result.report, images1 = result.images, links1 = result.links, htmls1 = result.htmls;

@@ -158,9 +162,9 @@ if (_probe === 'JS')

case 9:
_b.sent();
_a.sent();
return [4 /*yield*/, processLinks(links1, 'document.xml', zip, templatePath)];
case 10:
_b.sent();
_a.sent();
return [4 /*yield*/, processHtmls(htmls1, 'document.xml', zip, templatePath)];
case 11:
_b.sent();
_a.sent();
files = [];

@@ -183,3 +187,3 @@ zip.forEach(function (filePath) { return __awaiter(_this, void 0, void 0, function () {

i = 0;
_b.label = 12;
_a.label = 12;
case 12:

@@ -191,3 +195,3 @@ if (!(i < files.length)) return [3 /*break*/, 20];

case 13:
raw = _b.sent();
raw = _a.sent();
if (raw == null)

@@ -197,7 +201,11 @@ throw new Error(filePath + " could not be read");

case 14:
js0 = _b.sent();
js0 = _a.sent();
js = preprocessTemplate_1.default(js0, createOptions);
return [4 /*yield*/, processTemplate_1.produceJsReport(queryResult, js, createOptions)];
case 15:
_a = _b.sent(), report2 = _a.report, images2 = _a.images, links2 = _a.links, htmls2 = _a.htmls;
result_1 = _a.sent();
if (result_1.status === 'errors') {
throw result_1.errors;
}
report2 = result_1.report, images2 = result_1.images, links2 = result_1.links, htmls2 = result_1.htmls;
images = timm_1.merge(images, images2);

@@ -214,10 +222,10 @@ links = timm_1.merge(links, links2);

case 16:
_b.sent();
_a.sent();
return [4 /*yield*/, processLinks(links2, 'document.xml', zip, templatePath)];
case 17:
_b.sent();
_a.sent();
return [4 /*yield*/, processHtmls(htmls2, 'document.xml', zip, templatePath)];
case 18:
_b.sent();
_b.label = 19;
_a.sent();
_a.label = 19;
case 19:

@@ -232,3 +240,3 @@ i++;

case 21:
contentTypesXml = _b.sent();
contentTypesXml = _a.sent();
if (contentTypesXml == null)

@@ -238,3 +246,3 @@ throw new Error(contentTypesPath + " could not be read");

case 22:
contentTypes_1 = _b.sent();
contentTypes_1 = _a.sent();
ensureContentType = function (extension, contentType) {

@@ -266,3 +274,3 @@ var children = contentTypes_1._children;

zip_1.zipSetText(zip, contentTypesPath, finalContentTypesXml);
_b.label = 23;
_a.label = 23;
case 23:

@@ -275,3 +283,3 @@ // ---------------------------------------------------------

case 24:
output = _b.sent();
output = _a.sent();
return [2 /*return*/, output];

@@ -278,0 +286,0 @@ }

import { Node, CreateReportOptions, Images, Links, Htmls } from './types';
declare const extractQuery: (template: Node, options: CreateReportOptions) => Promise<string | undefined>;
declare type ReportOutput = {
status: 'success';
report: Node;

@@ -8,4 +9,7 @@ images: Images;

htmls: Htmls;
} | {
status: 'errors';
errors: Error[];
};
declare const produceJsReport: (data: any, template: Node, options: CreateReportOptions) => Promise<ReportOutput>;
export { extractQuery, produceJsReport };

@@ -87,3 +87,3 @@ "use strict";

parent_2._tag === 'w:t')) return [3 /*break*/, 3];
return [4 /*yield*/, processText(null, nodeIn, ctx)];
return [4 /*yield*/, processText(null, nodeIn, ctx, options.failFast)];
case 2:

@@ -102,5 +102,5 @@ _a.sent();

var produceJsReport = function (data, template, options) { return __awaiter(void 0, void 0, void 0, function () {
var out, ctx, nodeIn, nodeOut, move, deltaJump, curLoop, nextSibling, refNode, refNodeLevel, parent_3, tag, fRemoveNode, buffers, nodeOutParent, imgNode, parent_4, linkNode, parent_5, htmlNode, parent_6, tag, newNode, parent_7, newNodeAsTextNode, _a;
return __generator(this, function (_b) {
switch (_b.label) {
var out, ctx, nodeIn, nodeOut, move, deltaJump, errors, curLoop, nextSibling, refNode, refNodeLevel, parent_3, tag, fRemoveNode, buffers, nodeOutParent, imgNode, parent_4, linkNode, parent_5, htmlNode, parent_6, tag, newNode, parent_7, result, newNodeAsTextNode;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:

@@ -132,3 +132,4 @@ out = reportUtils_1.cloneNodeWithoutChildren(template);

deltaJump = 0;
_b.label = 1;
errors = [];
_a.label = 1;
case 1:

@@ -316,12 +317,17 @@ if (!true) return [3 /*break*/, 5];

parent_7._tag === 'w:t')) return [3 /*break*/, 3];
newNodeAsTextNode = newNode;
_a = newNodeAsTextNode;
return [4 /*yield*/, processText(data, nodeIn, ctx)];
return [4 /*yield*/, processText(data, nodeIn, ctx, options.failFast)];
case 2:
_a._text = _b.sent();
_b.label = 3;
result = _a.sent();
if (typeof result === 'string') {
newNodeAsTextNode = newNode;
newNodeAsTextNode._text = result;
}
else {
errors.push.apply(errors, result);
}
_a.label = 3;
case 3:
// Execute the move in the output tree
nodeOut = newNode;
_b.label = 4;
_a.label = 4;
case 4:

@@ -339,8 +345,15 @@ // Correct output tree level in case of a JUMP

return [3 /*break*/, 1];
case 5: return [2 /*return*/, {
report: out,
images: ctx.images,
links: ctx.links,
htmls: ctx.htmls,
}];
case 5:
if (errors.length > 0)
return [2 /*return*/, {
status: 'errors',
errors: errors,
}];
return [2 /*return*/, {
status: 'success',
report: out,
images: ctx.images,
links: ctx.links,
htmls: ctx.htmls,
}];
}

@@ -350,4 +363,4 @@ });

exports.produceJsReport = produceJsReport;
var processText = function (data, node, ctx) { return __awaiter(void 0, void 0, void 0, function () {
var cmdDelimiter, text, segments, outText, idx, segment, cmdResultText;
var processText = function (data, node, ctx, failFast) { return __awaiter(void 0, void 0, void 0, function () {
var cmdDelimiter, text, segments, outText, errors, idx, segment, cmdResultText;
return __generator(this, function (_a) {

@@ -365,2 +378,3 @@ switch (_a.label) {

outText = '';
errors = [];
idx = 0;

@@ -386,7 +400,14 @@ _a.label = 1;

if (cmdResultText != null) {
outText += cmdResultText;
appendTextToTagBuffers(cmdResultText, ctx, {
fCmd: false,
fInsertedText: true,
});
if (cmdResultText instanceof Error) {
if (failFast)
throw cmdResultText;
errors.push(cmdResultText);
}
else {
outText += cmdResultText;
appendTextToTagBuffers(cmdResultText, ctx, {
fCmd: false,
fInsertedText: true,
});
}
}

@@ -400,3 +421,6 @@ _a.label = 3;

return [3 /*break*/, 1];
case 5: return [2 /*return*/, outText];
case 5:
if (errors.length > 0)
return [2 /*return*/, errors];
return [2 /*return*/, outText];
}

@@ -510,3 +534,3 @@ });

err_1 = _a.sent();
throw new Error("Error executing command: " + cmd + " " + err_1.message);
return [2 /*return*/, new Error("Error executing command: " + cmd + " " + err_1.message)];
case 27: return [2 /*return*/];

@@ -653,69 +677,85 @@ }

};
/* eslint-disable */
var imageToContext = function (ctx, img) {
if (!(typeof img.extension === 'string')) {
throw new Error('An extension (e.g. `.png`) needs to be provided when providing an image or a thumbnail.');
}
ctx.imageId += 1;
var id = String(ctx.imageId);
var relId = "img" + id;
ctx.images[relId] = img;
return relId;
};
var processImage = function (ctx, imagePars) { return __awaiter(void 0, void 0, void 0, function () {
var cx, cy, id, relId, _a, _b, alt, node, pic, drawing;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
cx = (imagePars.width * 360e3).toFixed(0);
cy = (imagePars.height * 360e3).toFixed(0);
ctx.imageId += 1;
id = String(ctx.imageId);
relId = "img" + id;
_a = ctx.images;
_b = relId;
return [4 /*yield*/, getImageData(imagePars)];
case 1:
_a[_b] = _c.sent();
alt = imagePars.alt || 'desc';
node = reportUtils_1.newNonTextNode;
pic = node('pic:pic', { 'xmlns:pic': 'http://schemas.openxmlformats.org/drawingml/2006/picture' }, [
node('pic:nvPicPr', {}, [
node('pic:cNvPr', { id: '0', name: "Picture " + id, descr: alt }),
node('pic:cNvPicPr', {}, [
node('a:picLocks', { noChangeAspect: '1', noChangeArrowheads: '1' }),
]),
]),
node('pic:blipFill', {}, [
node('a:blip', { 'r:embed': relId, cstate: 'print' }, [
node('a:extLst', {}, [
node('a:ext', { uri: '{28A0092B-C50C-407E-A947-70E740481C1C}' }, [
node('a14:useLocalDpi', {
'xmlns:a14': 'http://schemas.microsoft.com/office/drawing/2010/main',
val: '0',
}),
]),
]),
]),
node('a:srcRect'),
node('a:stretch', {}, [node('a:fillRect')]),
]),
node('pic:spPr', { bwMode: 'auto' }, [
node('a:xfrm', {}, [
node('a:off', { x: '0', y: '0' }),
node('a:ext', { cx: cx, cy: cy }),
]),
node('a:prstGeom', { prst: 'rect' }, [node('a:avLst')]),
node('a:noFill'),
node('a:ln', {}, [node('a:noFill')]),
]),
]);
drawing = node('w:drawing', {}, [
node('wp:inline', { distT: '0', distB: '0', distL: '0', distR: '0' }, [
node('wp:extent', { cx: cx, cy: cy }),
node('wp:docPr', { id: id, name: "Picture " + id, descr: alt }),
node('wp:cNvGraphicFramePr', {}, [
node('a:graphicFrameLocks', {
'xmlns:a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
noChangeAspect: '1',
}),
]),
node('a:graphic', { 'xmlns:a': 'http://schemas.openxmlformats.org/drawingml/2006/main' }, [
node('a:graphicData', { uri: 'http://schemas.openxmlformats.org/drawingml/2006/picture' }, [pic]),
]),
]),
]);
ctx.pendingImageNode = drawing;
return [2 /*return*/];
var cx, cy, imgRelId, id, alt, node, extNodes, thumbnail, thumbRelId, pic, drawing;
var _a;
return __generator(this, function (_b) {
cx = (imagePars.width * 360e3).toFixed(0);
cy = (imagePars.height * 360e3).toFixed(0);
imgRelId = imageToContext(ctx, getImageData(imagePars));
id = String(ctx.imageId);
alt = imagePars.alt || 'desc';
node = reportUtils_1.newNonTextNode;
extNodes = [];
extNodes.push(node('a:ext', { uri: '{28A0092B-C50C-407E-A947-70E740481C1C}' }, [
node('a14:useLocalDpi', {
'xmlns:a14': 'http://schemas.microsoft.com/office/drawing/2010/main',
val: '0',
}),
]));
if (ctx.images[imgRelId].extension === '.svg') {
thumbnail = (_a = imagePars.thumbnail) !== null && _a !== void 0 ? _a : {
data: 'bm90aGluZwo=',
extension: '.png',
};
thumbRelId = imageToContext(ctx, thumbnail);
extNodes.push(node('a:ext', { uri: '{96DAC541-7B7A-43D3-8B79-37D633B846F1}' }, [
node('asvg:svgBlip', {
'xmlns:asvg': 'http://schemas.microsoft.com/office/drawing/2016/SVG/main',
'r:embed': imgRelId,
}),
]));
// For SVG the thumb is placed where the image normally goes.
imgRelId = thumbRelId;
}
pic = node('pic:pic', { 'xmlns:pic': 'http://schemas.openxmlformats.org/drawingml/2006/picture' }, [
node('pic:nvPicPr', {}, [
node('pic:cNvPr', { id: '0', name: "Picture " + id, descr: alt }),
node('pic:cNvPicPr', {}, [
node('a:picLocks', { noChangeAspect: '1', noChangeArrowheads: '1' }),
]),
]),
node('pic:blipFill', {}, [
node('a:blip', { 'r:embed': imgRelId, cstate: 'print' }, [
node('a:extLst', {}, extNodes),
]),
node('a:srcRect'),
node('a:stretch', {}, [node('a:fillRect')]),
]),
node('pic:spPr', { bwMode: 'auto' }, [
node('a:xfrm', {}, [
node('a:off', { x: '0', y: '0' }),
node('a:ext', { cx: cx, cy: cy }),
]),
node('a:prstGeom', { prst: 'rect' }, [node('a:avLst')]),
node('a:noFill'),
node('a:ln', {}, [node('a:noFill')]),
]),
]);
drawing = node('w:drawing', {}, [
node('wp:inline', { distT: '0', distB: '0', distL: '0', distR: '0' }, [
node('wp:extent', { cx: cx, cy: cy }),
node('wp:docPr', { id: id, name: "Picture " + id, descr: alt }),
node('wp:cNvGraphicFramePr', {}, [
node('a:graphicFrameLocks', {
'xmlns:a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
noChangeAspect: '1',
}),
]),
node('a:graphic', { 'xmlns:a': 'http://schemas.openxmlformats.org/drawingml/2006/main' }, [
node('a:graphicData', { uri: 'http://schemas.openxmlformats.org/drawingml/2006/picture' }, [pic]),
]),
]),
]);
ctx.pendingImageNode = drawing;
return [2 /*return*/];
});

@@ -722,0 +762,0 @@ }); };

@@ -74,3 +74,3 @@ "use strict";

node._children.forEach(function (child) {
child._parent = node; // eslint-disable-line
child._parent = node;
});

@@ -87,3 +87,3 @@ return node;

parent._children.push(child);
child._parent = parent; // eslint-disable-line
child._parent = parent;
return child;

@@ -90,0 +90,0 @@ };

@@ -33,11 +33,52 @@ /// <reference types="node" />

export declare type UserOptions = {
/**
* Docx file template as a NodeJS Buffer or Buffer-like object in Browsers.
*/
template: Buffer;
/**
* Object of data to be injected or a (async) function that resolves to the data. The function gets as an argument the contents of the QUERY command as a string.
*/
data?: ReportData | QueryResolver;
/**
* Gets injected into data function as second argument.
*/
queryVars?: any;
/**
* Defines a custom command delimiter. This can be a String e.g. '+++' or an Array of Strings with length 2: ['{', '}'] in which the first element serves as the start delimiter and the second as the end delimiter.
*/
cmdDelimiter?: string | [string, string];
/**
* Can be used to change the delimiter in generated XML.
*/
literalXmlDelimiter?: string;
/**
* Handle linebreaks in result of commands as actual linebreaks (Default: true)
*/
processLineBreaks?: boolean;
/**
* INSECURE: Set this option to true to disable running all commands in a new JS-VM. USE ONLY WITH TRUSTED TEMPLATES. Beware of arbitrary code injection risks. Can slightly improve performance on complex templates.
*/
noSandbox?: boolean;
/**
* Custom sandbox. See documentation for details.
*/
runJs?: RunJSFunc;
/**
* Add functions or other static data to this option to have access to it in your commands.
*
* ```js
* additionalJsContext: {
* qrCode: url => {
* const dataUrl = createQrImage(url, { size: 500 });
* const data = dataUrl.slice('data:image/gif;base64,'.length);
* return { width: 6, height: 6, data, extension: '.gif' };
* },
* }
* ```
*/
additionalJsContext?: Object;
/**
* Whether to fail on the first error encountered in the template. Defaults to true. Can be used to collect all errors in a template (e.g. misspelled commands) before failing.
*/
failFast?: boolean;
};

@@ -51,2 +92,3 @@ export declare type CreateReportOptions = {

additionalJsContext: Object;
failFast: boolean;
};

@@ -118,2 +160,3 @@ export declare type Context = {

data: ArrayBuffer | string;
thumbnail?: Image;
extension?: string;

@@ -120,0 +163,0 @@ alt?: string;

import JSZip from 'jszip';
declare const zipLoad: (inputFile: ArrayBuffer) => Promise<JSZip>;
declare const zipGetText: (zip: JSZip, filename: string) => Promise<string>;
declare const zipGetText: (zip: JSZip, filename: string) => Promise<string> | null;
declare const zipSetText: (zip: JSZip, filename: string, data: string) => JSZip;

@@ -5,0 +5,0 @@ declare const zipSetBinary: (zip: JSZip, filename: string, data: ArrayBuffer) => JSZip;

@@ -10,3 +10,6 @@ "use strict";

var zipGetText = function (zip, filename) {
return zip.file(filename).async('text');
var file_in_zip = zip.file(filename);
if (!file_in_zip)
return null;
return file_in_zip.async('text');
};

@@ -13,0 +16,0 @@ exports.zipGetText = zipGetText;

{
"name": "docx-templates",
"version": "4.0.0",
"version": "4.1.0",
"description": "Template-based docx report creation",

@@ -30,3 +30,3 @@ "main": "lib/index.js",

"jest": "jest --watch --coverage",
"test": "yarn prettier-check && yarn testCovFull",
"test": "yarn lint && yarn testCovFull",
"testCovFull": "yarn testCovPrepare && yarn testDev && yarn testCovReport",

@@ -36,4 +36,4 @@ "testCovPrepare": "rm -rf ./coverage .nyc_output .nyc_tmp && mkdir .nyc_tmp",

"testCovReport": "cp -r .nyc_tmp .nyc_output && nyc report --reporter=html --reporter=lcov --reporter=text",
"prettier": "prettier --write \"src/**/*.ts\"",
"prettier-check": "prettier --check \"src/**/*.ts\""
"lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
"lint-fix": "eslint --fix \"src/**/*.{js,jsx,ts,tsx}\""
},

@@ -44,3 +44,3 @@ "engines": {

"dependencies": {
"jszip": "^3.2.2",
"jszip": "^3.4.0",
"sax": "1.2.4",

@@ -51,14 +51,21 @@ "timm": "^1.6.2"

"@types/jest": "^25.1.4",
"@types/jszip": "^3.1.7",
"@types/node": "^13.9.2",
"@types/node": "^13.13.2",
"@types/qrcode": "^1.3.4",
"@types/sax": "^1.2.1",
"coveralls": "^3.0.11",
"jest": "^25.1.0",
"@typescript-eslint/eslint-plugin": "^2.29.0",
"@typescript-eslint/parser": "^2.29.0",
"coveralls": "^3.0.13",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jest": "^23.8.2",
"eslint-plugin-prettier": "^3.1.2",
"jest": "^25.4.0",
"mockdate": "^2.0.5",
"nyc": "^15.0.1",
"prettier": "^2.0.4",
"oao": "^1.8.0",
"prettier": "^2.0.5",
"qrcode": "^1.4.4",
"rimraf": "^3.0.2",
"ts-jest": "^25.2.1",
"ts-jest": "^25.4.0",
"typescript": "^3.8.3"

@@ -65,0 +72,0 @@ },

@@ -283,4 +283,28 @@ # Docx-templates [![Build Status](https://travis-ci.org/guigrpa/docx-templates.svg)](https://travis-ci.org/guigrpa/docx-templates) [![Coverage Status](https://coveralls.io/repos/github/guigrpa/docx-templates/badge.svg?branch=master)](https://coveralls.io/github/guigrpa/docx-templates?branch=master) [![npm version](https://img.shields.io/npm/v/docx-templates.svg)](https://www.npmjs.com/package/docx-templates)

* `data`: either an ArrayBuffer or a base64 string with the image data
* `extension` _[optional]_: e.g. `.png`
* `extension`: e.g. `.png`
* `thumbnail` _[optional]_: when injecting an SVG image, a fallback non-SVG (png/jpg/gif, etc.) image can be provided. This thumbnail is used when SVG images are not supported (e.g. older versions of Word) or when the document is previewed by e.g. Windows Explorer. See usage example below.
In the .docx template:
```
+++IMAGE injectSvg()+++
```
In the `createReport` call:
```js
additionalJsContext: {
injectSvg: () => {
const svg_data = Buffer.from(`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" height="100" width="100" style="stroke:#ff0000; fill: #0000ff"/>
</svg>`, 'utf-8');
// Providing a thumbnail is technically optional, as newer versions of Word will just ignore it.
const thumbnail = {
data: fs.readFileSync('sample.png'),
extension: '.png',
};
return { width: 6, height: 6, data: svg_data, extension: '.svg', thumbnail };
}
}
```
### `LINK`

@@ -393,3 +417,28 @@

## Error handling
By default, `createReport` will throw an error the moment it encounters a problem with the template, such as a bad command (i.e. it 'fails fast'). In some cases, however, you may want to collect all errors that may exist in the template before failing. For example, this is useful when you are letting your users create templates interactively. You can disable fast-failing by providing the `failFast: false` parameter as shown below. This will make `createReport` throw an array of errors instead of a single error so you can get a more complete picture of what is wrong with the template.
```typescript
try {
createReport({
template,
data: {
name: 'John',
surname: 'Appleseed',
},
failFast: false,
});
} catch (errors) {
if (Array.isArray(errors)) {
// An array of errors likely caused by bad commands in the template.
console.log(errors);
} else {
// Not an array of template errors, indicating something more serious.
throw errors;
}
}
```
## [Changelog](https://github.com/guigrpa/docx-templates/blob/master/CHANGELOG.md)

@@ -396,0 +445,0 @@

@@ -15,6 +15,3 @@ {

"src"
],
"exclude": [
"src/__tests__/**/*"
]
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc