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
2
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.11.4 to 4.11.5

5

CHANGELOG.md

@@ -0,1 +1,6 @@

## 4.11.5 (2024-03-24)
- [#340](https://github.com/guigrpa/docx-templates/issues/340) Fix for infinite loop bug: don't allow nested IFs on same `w:p` or `w:tr` tag.
- [#356](https://github.com/guigrpa/docx-templates/issues/356) Simplify documentation of INS commands.
- [#355](https://github.com/guigrpa/docx-templates/issues/355) Retain original sandbox errors (from different JavaScript realms) without coercion.
## 4.11.4 (2024-01-12)

@@ -2,0 +7,0 @@ - Replace weak `Object` types of `runJs` arguments.

5

lib/bundled.d.ts

@@ -170,2 +170,4 @@ type Buffer = ArrayBufferLike;

textRunPropsNode?: NonTextNode;
pIfCheckMap: Map<Node, string>;
trIfCheckMap: Map<Node, string>;
};

@@ -287,2 +289,3 @@ type Images = {

declare function isError(err: unknown): err is Error;
/**

@@ -330,2 +333,2 @@ * Thrown when `rejectNullish` is set to `true` and a command returns `null` or `undefined`.

export { CommandExecutionError, CommandSyntaxError, ImageError, IncompleteConditionalStatementError, InternalError, InvalidCommandError, NullishCommandResultError, ObjectCommandResultError, QueryResolver, TemplateParseError, UnterminatedForLoopError, createReport, createReport as default, getMetadata, listCommands };
export { CommandExecutionError, CommandSyntaxError, ImageError, IncompleteConditionalStatementError, InternalError, InvalidCommandError, NullishCommandResultError, ObjectCommandResultError, QueryResolver, TemplateParseError, UnterminatedForLoopError, createReport, createReport as default, getMetadata, isError, listCommands };

1

lib/errors.d.ts
import { LoopStatus } from './types';
export declare function isError(err: unknown): err is Error;
/**

@@ -3,0 +4,0 @@ * Thrown when `rejectNullish` is set to `true` and a command returns `null` or `undefined`.

@@ -18,3 +18,8 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.UnterminatedForLoopError = exports.IncompleteConditionalStatementError = exports.TemplateParseError = exports.InternalError = exports.ImageError = exports.CommandExecutionError = exports.InvalidCommandError = exports.CommandSyntaxError = exports.ObjectCommandResultError = exports.NullishCommandResultError = void 0;
exports.UnterminatedForLoopError = exports.IncompleteConditionalStatementError = exports.TemplateParseError = exports.InternalError = exports.ImageError = exports.CommandExecutionError = exports.InvalidCommandError = exports.CommandSyntaxError = exports.ObjectCommandResultError = exports.NullishCommandResultError = exports.isError = void 0;
function isError(err) {
return (err instanceof Error ||
(typeof err === 'object' && !!err && 'name' in err && 'message' in err));
}
exports.isError = isError;
/**

@@ -74,3 +79,3 @@ * Thrown when `rejectNullish` is set to `true` and a command returns `null` or `undefined`.

function CommandExecutionError(err, command) {
var _this = _super.call(this, "Error executing command '".concat(command, "': ").concat(err.message)) || this;
var _this = _super.call(this, "Error executing command '".concat(command, "': ").concat(err.name, ": ").concat(err.message)) || this;
Object.setPrototypeOf(_this, CommandExecutionError.prototype);

@@ -77,0 +82,0 @@ _this.command = command;

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

err_1 = _b.sent();
e = err_1 instanceof Error ? err_1 : new Error("".concat(err_1));
e = (0, errors_1.isError)(err_1) ? err_1 : new Error("".concat(err_1));
if (!(ctx.options.errorHandler != null)) return [3 /*break*/, 10];

@@ -108,0 +108,0 @@ context = sandbox;

@@ -80,2 +80,5 @@ "use strict";

options: options,
// To verfiy we don't have a nested if within the same p or tr tag
pIfCheckMap: new Map(),
trIfCheckMap: new Map(),
};

@@ -187,5 +190,26 @@ }

};
var findParentPorTrNode = function (node) {
var parentNode = node._parent;
var resultNode = null;
while (parentNode != null && resultNode == null) {
var parentNodeTag = parentNode._fTextNode ? null : parentNode._tag;
if (parentNodeTag === 'w:p') {
// check also for w:tr tag
var grandParentNode = parentNode._parent != null ? parentNode._parent._parent : null;
if (grandParentNode != null &&
!grandParentNode._fTextNode &&
grandParentNode._tag === 'w:tr') {
resultNode = grandParentNode;
}
else {
resultNode = parentNode;
}
}
parentNode = parentNode._parent;
}
return resultNode;
};
function walkTemplate(data, template, ctx, processor) {
return __awaiter(this, void 0, void 0, function () {
var out, nodeIn, nodeOut, move, deltaJump, errors, curLoop, nextSibling, parent_3, tag, fRemoveNode, buffers, nodeOutParent, imgNode, captionNodes, parent_4, linkNode, parent_5, htmlNode, parent_6, tag, newNode, newNodeTag, parent_7, result, err, innermost_loop, err;
var out, nodeIn, nodeOut, move, deltaJump, errors, loopCount, curLoop, nextSibling, parent_3, tag, fRemoveNode, buffers, nodeOutParent, imgNode, captionNodes, parent_4, linkNode, parent_5, htmlNode, parent_6, tag, newNode, newNodeTag, parent_7, result, err, innermost_loop, err;
var _a;

@@ -200,2 +224,3 @@ return __generator(this, function (_b) {

errors = [];
loopCount = 0;
_b.label = 1;

@@ -234,4 +259,11 @@ case 1:

parent_3 = nodeIn._parent;
if (parent_3 == null)
if (parent_3 == null) {
debug_1.logger.debug("=== parent is null, breaking after ".concat(loopCount, " loops..."));
return [3 /*break*/, 5];
}
else if (loopCount > 1000000) {
// adding a emergency exit to avoid infit loops
debug_1.logger.debug("=== parent is still not null after ".concat(loopCount, " loops, something must be wrong ..."), debugPrintNode(parent_3));
throw new errors_1.InternalError('something went wrong with the document. Please review and try again');
}
nodeIn = parent_3;

@@ -413,2 +445,3 @@ ctx.level -= 1;

}
loopCount++;
return [3 /*break*/, 1];

@@ -611,3 +644,3 @@ case 5:

catch (e) {
if (!(e instanceof Error))
if (!(0, errors_1.isError)(e))
throw e;

@@ -647,3 +680,3 @@ throw new errors_1.ImageError(e, cmd);

err_1 = _b.sent();
if (!(err_1 instanceof Error))
if (!(0, errors_1.isError)(err_1))
throw err_1;

@@ -706,3 +739,3 @@ if (ctx.options.errorHandler != null) {

var processForIf = function (data, node, ctx, cmd, cmdName, cmdRest) { return __awaiter(void 0, void 0, void 0, function () {
var isIf, forMatch, varName, curLoop, parentLoopLevel, fParentIsExploring, loopOver, shouldRun;
var isIf, forMatch, varName, curLoop, parentPorTrNode, parentPorTrNodeTag, parentLoopLevel, fParentIsExploring, loopOver, shouldRun;
return __generator(this, function (_a) {

@@ -729,2 +762,27 @@ switch (_a.label) {

if (!!(curLoop && curLoop.varName === varName)) return [3 /*break*/, 6];
// Check whether we already started a nested IF without and END-IF for this p or tr tag
if (isIf) {
parentPorTrNode = findParentPorTrNode(node);
parentPorTrNodeTag = parentPorTrNode != null
? parentPorTrNode._fTextNode
? null
: parentPorTrNode._tag
: null;
if (parentPorTrNode != null) {
if (parentPorTrNodeTag === 'w:p') {
if (ctx.pIfCheckMap.has(parentPorTrNode) &&
ctx.pIfCheckMap.get(parentPorTrNode) !== cmd)
throw new errors_1.InvalidCommandError('Invalid IF command nested into another IF command on the same line', cmd);
else
ctx.pIfCheckMap.set(parentPorTrNode, cmd);
}
else if (parentPorTrNodeTag === 'w:tr') {
if (ctx.trIfCheckMap.has(parentPorTrNode) &&
ctx.trIfCheckMap.get(parentPorTrNode) !== cmd)
throw new errors_1.InvalidCommandError('Invalid IF command nested into another IF command on the same table row', cmd);
else
ctx.trIfCheckMap.set(parentPorTrNode, cmd);
}
}
}
parentLoopLevel = ctx.loops.length - 1;

@@ -775,2 +833,15 @@ fParentIsExploring = parentLoopLevel >= 0 && ctx.loops[parentLoopLevel].idx === -1;

throw new errors_1.InvalidCommandError("Unexpected ".concat(cmdName, " outside of ").concat(isIf ? 'IF statement' : 'FOR loop', " context"), cmd);
// Reset the if check flag for the corresponding p or tr parent node
var parentPorTrNode = findParentPorTrNode(node);
var parentPorTrNodeTag = parentPorTrNode != null
? parentPorTrNode._fTextNode
? null
: parentPorTrNode._tag
: null;
if (parentPorTrNodeTag === 'w:p') {
ctx.pIfCheckMap.delete(parentPorTrNode);
}
else if (parentPorTrNodeTag === 'w:tr') {
ctx.trIfCheckMap.delete(parentPorTrNode);
}
// First time we visit an END-IF node, we assign it the arbitrary name

@@ -777,0 +848,0 @@ // generated when the IF was processed

@@ -159,2 +159,4 @@ import { QualifiedAttribute } from 'sax';

textRunPropsNode?: NonTextNode;
pIfCheckMap: Map<Node, string>;
trIfCheckMap: Map<Node, string>;
};

@@ -161,0 +163,0 @@ export type Images = {

{
"name": "docx-templates",
"version": "4.11.4",
"version": "4.11.5",
"description": "Template-based docx report creation",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -245,38 +245,29 @@ # 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)

### `QUERY`
### Insert data with the `INS` command ( or using `=`, or nothing at all)
You can use GraphQL, SQL, whatever you want: the query will be passed unchanged to your `data` query resolver.
Inserts the result of a given JavaScript snippet as follows.
Using code like this:
```js
const report = await createReport({
template,
data: { name: 'John', surname: 'Appleseed' },
cmdDelimiter: ['+++', '+++'],
});
```
+++QUERY
query getData($projectId: Int!) {
project(id: $projectId) {
name
details { year }
people(sortedBy: "name") { name }
}
}
+++
And a template like this:
```
+++name+++ +++surname+++
```
For the following sections (except where noted), we assume the following dataset:
Will produce a result docx file that looks like this:
```js
const data = {
project: {
name: 'docx-templates',
details: { year: '2016' },
people: [{ name: 'John', since: 2015 }, { name: 'Robert', since: 2010 }],
},
};
```
John Appleseed
```
### `INS` (`=`, or nothing at all)
Inserts the result of a given JavaScript snippet:
Alternatively, you can use the more explicit `INS` (insert) command syntax.
```
+++INS project.name+++ (+++INS project.details.year+++)
or...
+++INS `${project.name} (${$details.year})`+++
+++INS name+++ +++INS surname+++
```

@@ -294,7 +285,6 @@

You can also use this shorthand notation:
You can also use `=` as shorthand notation instead of `INS`:
```
+++= project.name+++ (+++= project.details.year+++)
+++= `${project.name} (${$details.year})`+++
+++= name+++ +++= surname+++
```

@@ -305,3 +295,3 @@

```
{project.name} ({project.details.year})
{name} {surname}
```

@@ -317,2 +307,30 @@

### `QUERY`
You can use GraphQL, SQL, whatever you want: the query will be passed unchanged to your `data` query resolver.
```
+++QUERY
query getData($projectId: Int!) {
project(id: $projectId) {
name
details { year }
people(sortedBy: "name") { name }
}
}
+++
```
For the following sections (except where noted), we assume the following dataset:
```js
const data = {
project: {
name: 'docx-templates',
details: { year: '2016' },
people: [{ name: 'John', since: 2015 }, { name: 'Robert', since: 2010 }],
},
};
```
### `EXEC` (`!`)

@@ -319,0 +337,0 @@

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

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