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.1.0 to 4.1.1

7

CHANGELOG.md

@@ -0,5 +1,8 @@

## 4.1.1 (2020-06-06)
* [PR #121](https://github.com/guigrpa/docx-templates/pull/121) Improved detection of built-in commands in templates to avoid confusion with javascript symbols.
* [#107](https://github.com/guigrpa/docx-templates/issues/107) Library now correctly recognizes user-defined commands with non-alphanumeric names (like Chinese characters).
* [#131](https://github.com/guigrpa/docx-templates/issues/131): .docx template files originating from Office365 or SharePoint can now be used (PR [#132](https://github.com/guigrpa/docx-templates/pull/121))
## 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.

@@ -6,0 +9,0 @@ * #33 SVGs can now be inserted into the templates directly, based on excellent work by @lwallent.

declare const _default: {
info: {
(...data: any[]): void;
(message?: any, ...optionalParams: any[]): void;
(message?: any, ...optionalParams: any[]): void;
};
debug: {
(...data: any[]): void;
(message?: any, ...optionalParams: any[]): void;
(message?: any, ...optionalParams: any[]): void;
};
};
export default _default;

@@ -6,4 +6,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.createReport = void 0;
var main_1 = __importDefault(require("./main"));
exports.createReport = main_1.default;
exports.default = main_1.default;

@@ -1,4 +0,4 @@

import { Context } from './types';
declare const runUserJsAndGetString: (data: any, code: string, ctx: Context) => Promise<string>;
declare const runUserJsAndGetRaw: (data: any, code: string, ctx: Context) => Promise<any>;
import { ReportData, Context } from './types';
declare const runUserJsAndGetString: (data: ReportData | undefined, code: string, ctx: Context) => Promise<string>;
declare const runUserJsAndGetRaw: (data: ReportData | undefined, code: string, ctx: Context) => Promise<any>;
export { runUserJsAndGetString, runUserJsAndGetRaw };

@@ -42,2 +42,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.runUserJsAndGetRaw = exports.runUserJsAndGetString = void 0;
var vm_1 = __importDefault(require("vm"));

@@ -44,0 +45,0 @@ var timm_1 = require("timm");

@@ -1,2 +0,3 @@

import { UserOptions, Node } from './types';
import { UserOptions, Node, NonTextNode } from './types';
import JSZip from 'jszip';
/**

@@ -7,3 +8,3 @@ * Create Report from docx template

* ```js
* createReport({
* const report = await createReport({
* template,

@@ -36,2 +37,4 @@ * data: query => graphqlServer.execute(query),

declare function createReport(options: UserOptions, _probe: 'XML'): Promise<string>;
export declare function readContentTypes(zip: JSZip): Promise<NonTextNode>;
export declare function getMainDoc(contentTypes: NonTextNode): string;
export default createReport;

@@ -42,2 +42,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getMainDoc = exports.readContentTypes = void 0;
var timm_1 = require("timm");

@@ -52,2 +53,3 @@ var zip_1 = require("./zip");

var DEFAULT_LITERAL_XML_DELIMITER = '||';
var CONTENT_TYPES_PATH = '[Content_Types].xml';
// TODO: remove

@@ -57,3 +59,3 @@ var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;

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, result_1, report2, images2, links2, htmls2, xml, segments, documentComponent, contentTypesPath, contentTypesXml, contentTypes_1, ensureContentType, finalContentTypesXml, output;
var template, data, queryVars, templatePath, literalXmlDelimiter, createOptions, xmlOptions, zip, contentTypes, mainDocument, 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, ensureContentType, finalContentTypesXml, output;
var _this = this;

@@ -87,8 +89,13 @@ return __generator(this, function (_a) {

// ---------------------------------------------------------
DEBUG && debug_1.default.debug('finding main template file (e.g. document.xml)');
return [4 /*yield*/, readContentTypes(zip)];
case 2:
contentTypes = _a.sent();
mainDocument = getMainDoc(contentTypes);
DEBUG && debug_1.default.debug('Reading template...');
return [4 /*yield*/, zip_1.zipGetText(zip, templatePath + "/document.xml")];
case 2:
return [4 /*yield*/, zip_1.zipGetText(zip, templatePath + "/" + mainDocument)];
case 3:
templateXml = _a.sent();
if (templateXml == null)
throw new Error('document.xml could not be found');
throw new Error(mainDocument + " could not be found");
DEBUG && debug_1.default.debug("Template file length: " + templateXml.length);

@@ -98,3 +105,3 @@ DEBUG && debug_1.default.debug('Parsing XML...');

return [4 /*yield*/, xml_1.parseXml(templateXml)];
case 3:
case 4:
parseResult = _a.sent();

@@ -114,16 +121,16 @@ jsTemplate = parseResult;

queryResult = null;
if (!(typeof data === 'function')) return [3 /*break*/, 6];
if (!(typeof data === 'function')) return [3 /*break*/, 7];
DEBUG && debug_1.default.debug('Looking for the query in the template...');
return [4 /*yield*/, processTemplate_1.extractQuery(finalTemplate, createOptions)];
case 4:
case 5:
query = _a.sent();
DEBUG && debug_1.default.debug("Query: " + (query || 'no query found'));
return [4 /*yield*/, data(query, queryVars)];
case 5:
case 6:
queryResult = _a.sent();
return [3 /*break*/, 7];
case 6:
return [3 /*break*/, 8];
case 7:
queryResult = data;
_a.label = 7;
case 7:
_a.label = 8;
case 8:
// ---------------------------------------------------------

@@ -137,3 +144,3 @@ // Process document.xml:

return [4 /*yield*/, processTemplate_1.produceJsReport(queryResult, finalTemplate, createOptions)];
case 8:
case 9:
result = _a.sent();

@@ -157,14 +164,14 @@ if (result.status === 'errors') {

DEBUG && debug_1.default.debug('Writing report...');
zip_1.zipSetText(zip, templatePath + "/document.xml", reportXml);
zip_1.zipSetText(zip, templatePath + "/" + mainDocument, reportXml);
numImages = Object.keys(images1).length;
numHtmls = Object.keys(htmls1).length;
return [4 /*yield*/, processImages(images1, 'document.xml', zip, templatePath)];
case 9:
_a.sent();
return [4 /*yield*/, processLinks(links1, 'document.xml', zip, templatePath)];
return [4 /*yield*/, processImages(images1, mainDocument, zip, templatePath)];
case 10:
_a.sent();
return [4 /*yield*/, processHtmls(htmls1, 'document.xml', zip, templatePath)];
return [4 /*yield*/, processLinks(links1, mainDocument, zip, templatePath)];
case 11:
_a.sent();
return [4 /*yield*/, processHtmls(htmls1, mainDocument, zip, templatePath)];
case 12:
_a.sent();
files = [];

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

if (regex.test(filePath) &&
filePath !== templatePath + "/document.xml" &&
filePath !== templatePath + "/" + mainDocument &&
filePath.indexOf(templatePath + "/template") !== 0) {

@@ -188,9 +195,9 @@ files.push(filePath);

i = 0;
_a.label = 12;
case 12:
if (!(i < files.length)) return [3 /*break*/, 20];
_a.label = 13;
case 13:
if (!(i < files.length)) return [3 /*break*/, 21];
filePath = files[i];
DEBUG && debug_1.default.info("Processing " + filePath + "...");
return [4 /*yield*/, zip_1.zipGetText(zip, filePath)];
case 13:
case 14:
raw = _a.sent();

@@ -200,7 +207,7 @@ if (raw == null)

return [4 /*yield*/, xml_1.parseXml(raw)];
case 14:
case 15:
js0 = _a.sent();
js = preprocessTemplate_1.default(js0, createOptions);
return [4 /*yield*/, processTemplate_1.produceJsReport(queryResult, js, createOptions)];
case 15:
case 16:
result_1 = _a.sent();

@@ -221,54 +228,47 @@ if (result_1.status === 'errors') {

return [4 /*yield*/, processImages(images2, documentComponent, zip, templatePath)];
case 16:
_a.sent();
return [4 /*yield*/, processLinks(links2, 'document.xml', zip, templatePath)];
case 17:
_a.sent();
return [4 /*yield*/, processHtmls(htmls2, 'document.xml', zip, templatePath)];
return [4 /*yield*/, processLinks(links2, mainDocument, zip, templatePath)];
case 18:
_a.sent();
_a.label = 19;
return [4 /*yield*/, processHtmls(htmls2, mainDocument, zip, templatePath)];
case 19:
_a.sent();
_a.label = 20;
case 20:
i++;
return [3 /*break*/, 12];
case 20:
if (!(numImages || numHtmls)) return [3 /*break*/, 23];
DEBUG && debug_1.default.debug('Completing [Content_Types].xml...');
contentTypesPath = '[Content_Types].xml';
return [4 /*yield*/, zip_1.zipGetText(zip, contentTypesPath)];
return [3 /*break*/, 13];
case 21:
contentTypesXml = _a.sent();
if (contentTypesXml == null)
throw new Error(contentTypesPath + " could not be read");
return [4 /*yield*/, xml_1.parseXml(contentTypesXml)];
case 22:
contentTypes_1 = _a.sent();
ensureContentType = function (extension, contentType) {
var children = contentTypes_1._children;
if (children.filter(function (o) { return !o._fTextNode && o._attrs.Extension === extension; })
.length) {
return;
// ---------------------------------------------------------
// Process [Content_Types].xml
// ---------------------------------------------------------
if (numImages || numHtmls) {
DEBUG && debug_1.default.debug('Completing [Content_Types].xml...');
ensureContentType = function (extension, contentType) {
var children = contentTypes._children;
if (children.filter(function (o) { return !o._fTextNode && o._attrs.Extension === extension; })
.length) {
return;
}
reportUtils_1.addChild(contentTypes, reportUtils_1.newNonTextNode('Default', {
Extension: extension,
ContentType: contentType,
}));
};
if (numImages) {
DEBUG && debug_1.default.debug('Completing [Content_Types].xml for IMAGES...');
ensureContentType('png', 'image/png');
ensureContentType('jpg', 'image/jpeg');
ensureContentType('jpeg', 'image/jpeg');
ensureContentType('gif', 'image/gif');
ensureContentType('bmp', 'image/bmp');
ensureContentType('svg', 'image/svg+xml');
}
reportUtils_1.addChild(contentTypes_1, reportUtils_1.newNonTextNode('Default', {
Extension: extension,
ContentType: contentType,
}));
};
if (numImages) {
DEBUG && debug_1.default.debug('Completing [Content_Types].xml for IMAGES...');
ensureContentType('png', 'image/png');
ensureContentType('jpg', 'image/jpeg');
ensureContentType('jpeg', 'image/jpeg');
ensureContentType('gif', 'image/gif');
ensureContentType('bmp', 'image/bmp');
ensureContentType('svg', 'image/svg+xml');
if (numHtmls) {
DEBUG && debug_1.default.debug('Completing [Content_Types].xml for HTML...');
ensureContentType('html', 'text/html');
}
finalContentTypesXml = xml_1.buildXml(contentTypes, xmlOptions);
zip_1.zipSetText(zip, CONTENT_TYPES_PATH, finalContentTypesXml);
}
if (numHtmls) {
DEBUG && debug_1.default.debug('Completing [Content_Types].xml for HTML...');
ensureContentType('html', 'text/html');
}
finalContentTypesXml = xml_1.buildXml(contentTypes_1, xmlOptions);
zip_1.zipSetText(zip, contentTypesPath, finalContentTypesXml);
_a.label = 23;
case 23:
// ---------------------------------------------------------

@@ -279,3 +279,3 @@ // Zip the results

return [4 /*yield*/, zip_1.zipSave(zip)];
case 24:
case 22:
output = _a.sent();

@@ -287,2 +287,39 @@ return [2 /*return*/, output];

}
function readContentTypes(zip) {
return __awaiter(this, void 0, void 0, function () {
var contentTypesXml, node;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, zip_1.zipGetText(zip, CONTENT_TYPES_PATH)];
case 1:
contentTypesXml = _a.sent();
if (contentTypesXml == null)
throw new Error(CONTENT_TYPES_PATH + " could not be read");
return [4 /*yield*/, xml_1.parseXml(contentTypesXml)];
case 2:
node = _a.sent();
if (node._fTextNode)
throw new Error(CONTENT_TYPES_PATH + " is a text node when parsed");
return [2 /*return*/, node];
}
});
});
}
exports.readContentTypes = readContentTypes;
function getMainDoc(contentTypes) {
var MAIN_DOC_MIME = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml';
for (var _i = 0, _a = contentTypes._children; _i < _a.length; _i++) {
var t = _a[_i];
if (!t._fTextNode) {
if (t._attrs.ContentType === MAIN_DOC_MIME) {
var path = t._attrs.PartName;
if (path) {
return path.replace('/word/', '');
}
}
}
}
throw new Error("Could not find main document (e.g. document.xml) in " + CONTENT_TYPES_PATH);
}
exports.getMainDoc = getMainDoc;
// ==========================================

@@ -289,0 +326,0 @@ // Process images

@@ -1,2 +0,2 @@

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

@@ -13,3 +13,3 @@ declare type ReportOutput = {

};
declare const produceJsReport: (data: any, template: Node, options: CreateReportOptions) => Promise<ReportOutput>;
declare const produceJsReport: (data: ReportData | undefined, template: Node, options: CreateReportOptions) => Promise<ReportOutput>;
export { extractQuery, produceJsReport };

@@ -39,2 +39,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.produceJsReport = exports.extractQuery = void 0;
var reportUtils_1 = require("./reportUtils");

@@ -545,7 +546,8 @@ var jsSandbox_1 = require("./jsSandbox");

];
var builtInRegexes = builtInCommands.map(function (word) { return new RegExp("^" + word + "\\b"); });
var notBuiltIns = function (cmd) {
return !builtInCommands.some(function (word) { return new RegExp("^" + word).test(cmd.toUpperCase()); });
return !builtInRegexes.some(function (r) { return r.test(cmd.toUpperCase()); });
};
var getCommand = function (ctx) {
var cmd = ctx.cmd;
var cmd = ctx.cmd.trim();
if (cmd[0] === '*') {

@@ -564,3 +566,3 @@ var aliasName = cmd.slice(1).trim();

}
else if (notBuiltIns(cmd) && /^[a-zA-Z$`'"]/.test(cmd)) {
else if (notBuiltIns(cmd)) {
cmd = "INS " + cmd.trim();

@@ -567,0 +569,0 @@ }

import { Node, TextNode, NonTextNode, Context, LoopStatus } from './types';
declare const cloneNodeWithoutChildren: (node: Node) => Node;
declare const cloneNodeForLogging: (node: Node) => Object;
declare const getNextSibling: (node: Node) => TextNode | NonTextNode | null;
declare const getNextSibling: (node: Node) => Node | null;
declare const insertTextSiblingAfter: (textNode: TextNode) => TextNode;
declare const newNonTextNode: (tag: string, attrs?: {}, children?: Node[]) => NonTextNode;
declare const newNonTextNode: (tag: string, attrs?: {}, children?: Array<Node>) => NonTextNode;
declare const newTextNode: (text: string) => TextNode;

@@ -11,3 +11,3 @@ declare const addChild: (parent: Node, child: Node) => Node;

declare const isLoopExploring: (ctx: Context) => boolean;
declare const logLoop: (loops: LoopStatus[]) => void;
declare const logLoop: (loops: Array<LoopStatus>) => void;
export { cloneNodeWithoutChildren, cloneNodeForLogging, getNextSibling, insertTextSiblingAfter, newNonTextNode, newTextNode, addChild, getCurLoop, isLoopExploring, logLoop, };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.logLoop = exports.isLoopExploring = exports.getCurLoop = exports.addChild = exports.newTextNode = exports.newNonTextNode = exports.insertTextSiblingAfter = exports.getNextSibling = exports.cloneNodeForLogging = exports.cloneNodeWithoutChildren = void 0;
var timm_1 = require("timm");

@@ -4,0 +5,0 @@ var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;

@@ -20,2 +20,4 @@ /// <reference types="node" />

Extension?: string;
ContentType?: string;
PartName?: string;
};

@@ -22,0 +24,0 @@ };

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.buildXml = exports.parseXml = void 0;
var sax_1 = __importDefault(require("sax"));

@@ -8,0 +9,0 @@ var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.zipSave = exports.zipSetBase64 = exports.zipSetBinary = exports.zipSetText = exports.zipGetText = exports.zipLoad = void 0;
var jszip_1 = __importDefault(require("jszip"));

@@ -8,0 +9,0 @@ var zipLoad = function (inputFile) { return jszip_1.default.loadAsync(inputFile); };

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

@@ -47,8 +47,8 @@ "main": "lib/index.js",

"devDependencies": {
"@types/jest": "^25.1.4",
"@types/jest": "^25.2.3",
"@types/node": "^13.13.2",
"@types/qrcode": "^1.3.4",
"@types/sax": "^1.2.1",
"@typescript-eslint/eslint-plugin": "^2.29.0",
"@typescript-eslint/parser": "^2.29.0",
"@typescript-eslint/eslint-plugin": "^3.1.0",
"@typescript-eslint/parser": "^3.1.0",
"coveralls": "^3.0.13",

@@ -58,5 +58,5 @@ "eslint": "^6.8.0",

"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jest": "^23.8.2",
"eslint-plugin-jest": "^23.13.2",
"eslint-plugin-prettier": "^3.1.2",
"jest": "^25.4.0",
"jest": "^26.0.1",
"mockdate": "^2.0.5",

@@ -68,4 +68,4 @@ "nyc": "^15.0.1",

"rimraf": "^3.0.2",
"ts-jest": "^25.4.0",
"typescript": "^3.8.3"
"ts-jest": "^26.1.0",
"typescript": "^3.9.5"
},

@@ -72,0 +72,0 @@ "jest": {

@@ -47,3 +47,3 @@ # 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)

const buffer = createReport({
const buffer = await createReport({
template,

@@ -62,3 +62,3 @@ data: {

```js
createReport({
const report = await createReport({
template,

@@ -74,3 +74,3 @@ data: query => graphqlServer.execute(query),

```js
createReport({
const report = await createReport({
// ...

@@ -92,15 +92,2 @@ additionalJsContext: {

You can use different **left/right command delimiters** by passing an array to `cmdDelimiter`:
```js
createReport({
// ...
cmdDelimiter: ['{', '}'],
})
```
This allows much cleaner-looking templates!
Then you can add commands and JS snippets in your template like this: `{foo}`, `{project.name}` `{QUERY ...}`, `{FOR ...}`.
Check out the [Node examples folder](https://github.com/guigrpa/docx-templates/tree/master/packages/example-node).

@@ -147,3 +134,3 @@

You can find an example implementation of `saveDataToFile()` [in the Webpack example](./packages/example-webpack/client/index.js).
You can find an example implementation of `saveDataToFile()` [in the Webpack example](https://github.com/guigrpa/docx-templates/blob/79119723ff1c009b5bbdd28016558da9b405742f/examples/example-webpack/client/index.js#L82).

@@ -153,3 +140,3 @@ With the default configuration, browser usage can become slow with complex templates due to the usage of JS sandboxes for security reasons. _If the templates you'll be using with docx-templates can be trusted 100%, you can disable the security sandboxes by configuring `noSandbox: true`_. **Beware of arbitrary code injection risks**:

```js
createReport({
const report = await createReport({
// ...

@@ -163,3 +150,21 @@ // USE ONLY IN THE BROWSER, AND WITH TRUSTED TEMPLATES

### Browser compatibility caveat
Note that the JavaScript code in your docx template will be run as-is by the browser. Transpilers like Babel can't see this code, and won't be able to polyfill it. This means that the JS code in your template needs to be compatible with the browsers you are targeting. In other words: don't use fancy modern syntax and functions in your template if you want older browsers, like IE11, to be able to render it.
## Custom command delimiters
You can use different **left/right command delimiters** by passing an array to `cmdDelimiter`:
```js
const report = await createReport({
// ...
cmdDelimiter: ['{', '}'],
})
```
This allows much cleaner-looking templates!
Then you can add commands and JS snippets in your template like this: `{foo}`, `{project.name}` `{QUERY ...}`, `{FOR ...}`.
When choosing a delimiter, take care not to introduce conflicts with JS syntax, especially if you are planning to use larger JS code snippets in your templates. For example, with `['{', '}']` you may run into conflicts as the brackets in your JS code may be mistaken for command delimiters. As an alternative, consider using multi-character delimiters, like `{#` and `#}` (see issue [#102](https://github.com/guigrpa/docx-templates/issues/102)).
## Writing templates

@@ -287,4 +292,4 @@

* `width` in cm
* `height` in cm
* `width`: desired width of the image on the page _in cm_. Note that the aspect ratio should match that of the input image to avoid stretching.
* `height` desired height of the image on the page _in cm_.
* `data`: either an ArrayBuffer or a base64 string with the image data

@@ -426,7 +431,7 @@ * `extension`: e.g. `.png`

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.
By default, the Promise returned by `createReport` will reject with an error immediately when a problem is encountered in 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` reject with 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({
const report = await createReport({
template,

@@ -433,0 +438,0 @@ data: {

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