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.2.0 to 4.3.0

5

CHANGELOG.md

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

## 4.3.0 (2020-06-23)
* Feature: added `listCommands` function to find and list all commands in a document (see [issue #90](https://github.com/guigrpa/docx-templates/issues/90)).
* Minor refactoring.
* Updated jszip dependency.
## 4.2.0 (2020-06-15)

@@ -2,0 +7,0 @@ * Feature: added 'rejectNullish' setting. When set to `true`, this setting ensures `createReport` throws a `NullishCommandResultError` when the result of an INS, HTML, IMAGE, or LINK command is `null` or `undefined`. This is useful as nullish return values usually indicate a mistake in the template or the invoking code. Defaults to `false`.

15

lib/debug.d.ts

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

declare const _default: {
info: {
(...data: any[]): void;
(message?: any, ...optionalParams: any[]): void;
};
debug: {
(...data: any[]): void;
(message?: any, ...optionalParams: any[]): void;
};
declare type LogSink = (message?: any, ...optionalParams: any[]) => void;
export declare const logger: {
debug: LogSink;
};
export default _default;
export declare function setDebugLogSink(f: LogSink): void;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = { info: console.log, debug: console.log };
exports.setDebugLogSink = exports.logger = void 0;
exports.logger = { debug: function () { } };
function setDebugLogSink(f) {
exports.logger.debug = f;
}
exports.setDebugLogSink = setDebugLogSink;

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

import createReport from './main';
export { createReport };
import createReport, { listCommands } from './main';
export { createReport, listCommands };
export default createReport;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createReport = void 0;
var main_1 = __importDefault(require("./main"));
exports.listCommands = exports.createReport = void 0;
var main_1 = __importStar(require("./main"));
exports.createReport = main_1.default;
Object.defineProperty(exports, "listCommands", { enumerable: true, get: function () { return main_1.listCommands; } });
exports.default = main_1.default;

@@ -47,4 +47,3 @@ "use strict";

var errors_1 = require("./errors");
var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;
var log = DEBUG ? require('./debug').mainStory : null;
var debug_1 = require("./debug");
// Runs a user snippet in a sandbox, and returns the result.

@@ -100,3 +99,3 @@ // The snippet can return a Promise, which is then awaited.

ctx.jsSandbox = timm_1.omit(context, ['__code__', '__result__']);
DEBUG && log.debug('JS result', { attach: result });
debug_1.logger.debug('JS result', { attach: result });
return [2 /*return*/, result];

@@ -103,0 +102,0 @@ }

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

import { UserOptions, Node, NonTextNode } from './types';
/// <reference types="node" />
import { UserOptions, Node, NonTextNode, CommandSummary } from './types';
import JSZip from 'jszip';

@@ -36,4 +37,22 @@ /**

declare function createReport(options: UserOptions, _probe: 'XML'): Promise<string>;
/**
* Lists all the commands in a docx template.
*
* example:
* ```js
* const template_buffer = fs.readFileSync('template.docx');
* const commands = await listCommands(template_buffer, ['{', '}']);
* // `commands` will contain something like:
* [
* { raw: 'INS some_variable', code: 'some_variable', type: 'INS' },
* { raw: 'IMAGE svgImgFile()', code: 'svgImgFile()', type: 'IMAGE' },
* ]
* ```
*
* @param template the docx template as a Buffer-like object
* @param delimiter the command delimiter (defaults to ['+++', '+++'])
*/
export declare function listCommands(template: Buffer, delimiter?: string | [string, string]): Promise<CommandSummary[]>;
export declare function readContentTypes(zip: JSZip): Promise<NonTextNode>;
export declare function getMainDoc(contentTypes: NonTextNode): string;
export default createReport;

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

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

@@ -50,42 +50,20 @@ var zip_1 = require("./zip");

var reportUtils_1 = require("./reportUtils");
var debug_1 = __importDefault(require("./debug"));
var errors_1 = require("./errors");
var debug_1 = require("./debug");
var DEFAULT_CMD_DELIMITER = '+++';
var DEFAULT_LITERAL_XML_DELIMITER = '||';
var CONTENT_TYPES_PATH = '[Content_Types].xml';
// TODO: remove
var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;
function createReport(options, _probe) {
var TEMPLATE_PATH = 'word';
function parseTemplate(template) {
return __awaiter(this, void 0, void 0, function () {
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;
var zip, contentTypes, mainDocument, templateXml, tic, parseResult, jsTemplate, tac;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
DEBUG && debug_1.default.debug('Report options:', { attach: options });
template = options.template, data = options.data, queryVars = options.queryVars;
templatePath = 'word';
literalXmlDelimiter = options.literalXmlDelimiter || DEFAULT_LITERAL_XML_DELIMITER;
createOptions = {
cmdDelimiter: getCmdDelimiter(options.cmdDelimiter),
literalXmlDelimiter: literalXmlDelimiter,
processLineBreaks: options.processLineBreaks != null ? options.processLineBreaks : true,
noSandbox: options.noSandbox || false,
runJs: options.runJs,
additionalJsContext: options.additionalJsContext || {},
failFast: options.failFast == null ? true : options.failFast,
rejectNullish: options.rejectNullish == null ? false : options.rejectNullish,
};
xmlOptions = { literalXmlDelimiter: literalXmlDelimiter };
// ---------------------------------------------------------
// Unzip
// ---------------------------------------------------------
DEBUG && debug_1.default.debug('Unzipping...');
debug_1.logger.debug('Unzipping...');
return [4 /*yield*/, zip_1.zipLoad(template)];
case 1:
zip = _a.sent();
// ---------------------------------------------------------
// Read the 'document.xml' file (the template) and parse it
// ---------------------------------------------------------
DEBUG && debug_1.default.debug('finding main template file (e.g. document.xml)');
debug_1.logger.debug('finding main template file (e.g. document.xml)');
return [4 /*yield*/, readContentTypes(zip)];

@@ -95,4 +73,4 @@ case 2:

mainDocument = getMainDoc(contentTypes);
DEBUG && debug_1.default.debug('Reading template...');
return [4 /*yield*/, zip_1.zipGetText(zip, templatePath + "/" + mainDocument)];
debug_1.logger.debug('Reading template...');
return [4 /*yield*/, zip_1.zipGetText(zip, TEMPLATE_PATH + "/" + mainDocument)];
case 3:

@@ -102,4 +80,4 @@ templateXml = _a.sent();

throw new errors_1.TemplateParseError(mainDocument + " could not be found");
DEBUG && debug_1.default.debug("Template file length: " + templateXml.length);
DEBUG && debug_1.default.debug('Parsing XML...');
debug_1.logger.debug("Template file length: " + templateXml.length);
debug_1.logger.debug('Parsing XML...');
tic = new Date().getTime();

@@ -111,28 +89,52 @@ return [4 /*yield*/, xml_1.parseXml(templateXml)];

tac = new Date().getTime();
DEBUG &&
debug_1.default.debug("File parsed in " + (tac - tic) + " ms", {
attach: jsTemplate,
attachLevel: 'trace',
});
// ---------------------------------------------------------
// Preprocess template
// ---------------------------------------------------------
DEBUG && debug_1.default.debug('Preprocessing template...');
finalTemplate = preprocessTemplate_1.default(jsTemplate, createOptions);
debug_1.logger.debug("File parsed in " + (tac - tic) + " ms", {
attach: jsTemplate,
attachLevel: 'trace',
});
return [2 /*return*/, { jsTemplate: jsTemplate, mainDocument: mainDocument, zip: zip, contentTypes: contentTypes }];
}
});
});
}
function createReport(options, _probe) {
return __awaiter(this, void 0, void 0, function () {
var template, data, queryVars, literalXmlDelimiter, createOptions, xmlOptions, _a, jsTemplate, mainDocument, zip, contentTypes, 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;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
debug_1.logger.debug('Report options:', { attach: options });
template = options.template, data = options.data, queryVars = options.queryVars;
literalXmlDelimiter = options.literalXmlDelimiter || DEFAULT_LITERAL_XML_DELIMITER;
createOptions = {
cmdDelimiter: getCmdDelimiter(options.cmdDelimiter),
literalXmlDelimiter: literalXmlDelimiter,
processLineBreaks: options.processLineBreaks != null ? options.processLineBreaks : true,
noSandbox: options.noSandbox || false,
runJs: options.runJs,
additionalJsContext: options.additionalJsContext || {},
failFast: options.failFast == null ? true : options.failFast,
rejectNullish: options.rejectNullish == null ? false : options.rejectNullish,
};
xmlOptions = { literalXmlDelimiter: literalXmlDelimiter };
return [4 /*yield*/, parseTemplate(template)];
case 1:
_a = _b.sent(), jsTemplate = _a.jsTemplate, mainDocument = _a.mainDocument, zip = _a.zip, contentTypes = _a.contentTypes;
debug_1.logger.debug('Preprocessing template...');
finalTemplate = preprocessTemplate_1.default(jsTemplate, createOptions.cmdDelimiter);
queryResult = null;
if (!(typeof data === 'function')) return [3 /*break*/, 7];
DEBUG && debug_1.default.debug('Looking for the query in the template...');
if (!(typeof data === 'function')) return [3 /*break*/, 4];
debug_1.logger.debug('Looking for the query in the template...');
return [4 /*yield*/, processTemplate_1.extractQuery(finalTemplate, createOptions)];
case 5:
query = _a.sent();
DEBUG && debug_1.default.debug("Query: " + (query || 'no query found'));
case 2:
query = _b.sent();
debug_1.logger.debug("Query: " + (query || 'no query found'));
return [4 /*yield*/, data(query, queryVars)];
case 6:
queryResult = _a.sent();
return [3 /*break*/, 8];
case 7:
case 3:
queryResult = _b.sent();
return [3 /*break*/, 5];
case 4:
queryResult = data;
_a.label = 8;
case 8:
// ---------------------------------------------------------
_b.label = 5;
case 5:
// Process document.xml:

@@ -142,7 +144,6 @@ // - Generate the report

// - Images
// ---------------------------------------------------------
DEBUG && debug_1.default.debug('Generating report...');
debug_1.logger.debug('Generating report...');
return [4 /*yield*/, processTemplate_1.produceJsReport(queryResult, finalTemplate, createOptions)];
case 9:
result = _a.sent();
case 6:
result = _b.sent();
if (result.status === 'errors') {

@@ -154,25 +155,19 @@ throw result.errors;

return [2 /*return*/, report1];
// DEBUG &&
// log.debug('Report', {
// attach: report,
// attachLevel: 'debug',
// ignoreKeys: ['_parent', '_fTextNode', '_attrs'],
// });
DEBUG && debug_1.default.debug('Converting report to XML...');
debug_1.logger.debug('Converting report to XML...');
reportXml = xml_1.buildXml(report1, xmlOptions);
if (_probe === 'XML')
return [2 /*return*/, reportXml];
DEBUG && debug_1.default.debug('Writing report...');
zip_1.zipSetText(zip, templatePath + "/" + mainDocument, reportXml);
debug_1.logger.debug('Writing report...');
zip_1.zipSetText(zip, TEMPLATE_PATH + "/" + mainDocument, reportXml);
numImages = Object.keys(images1).length;
numHtmls = Object.keys(htmls1).length;
return [4 /*yield*/, processImages(images1, mainDocument, zip, templatePath)];
case 10:
_a.sent();
return [4 /*yield*/, processLinks(links1, mainDocument, zip, templatePath)];
case 11:
_a.sent();
return [4 /*yield*/, processHtmls(htmls1, mainDocument, zip, templatePath)];
case 12:
_a.sent();
return [4 /*yield*/, processImages(images1, mainDocument, zip, TEMPLATE_PATH)];
case 7:
_b.sent();
return [4 /*yield*/, processLinks(links1, mainDocument, zip, TEMPLATE_PATH)];
case 8:
_b.sent();
return [4 /*yield*/, processHtmls(htmls1, mainDocument, zip, TEMPLATE_PATH)];
case 9:
_b.sent();
files = [];

@@ -182,6 +177,6 @@ zip.forEach(function (filePath) { return __awaiter(_this, void 0, void 0, function () {

return __generator(this, function (_a) {
regex = new RegExp(templatePath + "\\/[^\\/]+\\.xml");
regex = new RegExp(TEMPLATE_PATH + "\\/[^\\/]+\\.xml");
if (regex.test(filePath) &&
filePath !== templatePath + "/" + mainDocument &&
filePath.indexOf(templatePath + "/template") !== 0) {
filePath !== TEMPLATE_PATH + "/" + mainDocument &&
filePath.indexOf(TEMPLATE_PATH + "/template") !== 0) {
files.push(filePath);

@@ -196,19 +191,19 @@ }

i = 0;
_a.label = 13;
case 13:
if (!(i < files.length)) return [3 /*break*/, 21];
_b.label = 10;
case 10:
if (!(i < files.length)) return [3 /*break*/, 18];
filePath = files[i];
DEBUG && debug_1.default.info("Processing " + filePath + "...");
debug_1.logger.debug("Processing " + filePath + "...");
return [4 /*yield*/, zip_1.zipGetText(zip, filePath)];
case 14:
raw = _a.sent();
case 11:
raw = _b.sent();
if (raw == null)
throw new errors_1.TemplateParseError(filePath + " could not be read");
return [4 /*yield*/, xml_1.parseXml(raw)];
case 15:
js0 = _a.sent();
js = preprocessTemplate_1.default(js0, createOptions);
case 12:
js0 = _b.sent();
js = preprocessTemplate_1.default(js0, createOptions.cmdDelimiter);
return [4 /*yield*/, processTemplate_1.produceJsReport(queryResult, js, createOptions)];
case 16:
result_1 = _a.sent();
case 13:
result_1 = _b.sent();
if (result_1.status === 'errors') {

@@ -227,21 +222,19 @@ throw result_1.errors;

documentComponent = segments[segments.length - 1];
return [4 /*yield*/, processImages(images2, documentComponent, zip, templatePath)];
return [4 /*yield*/, processImages(images2, documentComponent, zip, TEMPLATE_PATH)];
case 14:
_b.sent();
return [4 /*yield*/, processLinks(links2, mainDocument, zip, TEMPLATE_PATH)];
case 15:
_b.sent();
return [4 /*yield*/, processHtmls(htmls2, mainDocument, zip, TEMPLATE_PATH)];
case 16:
_b.sent();
_b.label = 17;
case 17:
_a.sent();
return [4 /*yield*/, processLinks(links2, mainDocument, zip, templatePath)];
i++;
return [3 /*break*/, 10];
case 18:
_a.sent();
return [4 /*yield*/, processHtmls(htmls2, mainDocument, zip, templatePath)];
case 19:
_a.sent();
_a.label = 20;
case 20:
i++;
return [3 /*break*/, 13];
case 21:
// ---------------------------------------------------------
// Process [Content_Types].xml
// ---------------------------------------------------------
if (numImages || numHtmls) {
DEBUG && debug_1.default.debug('Completing [Content_Types].xml...');
debug_1.logger.debug('Completing [Content_Types].xml...');
ensureContentType = function (extension, contentType) {

@@ -259,3 +252,3 @@ var children = contentTypes._children;

if (numImages) {
DEBUG && debug_1.default.debug('Completing [Content_Types].xml for IMAGES...');
debug_1.logger.debug('Completing [Content_Types].xml for IMAGES...');
ensureContentType('png', 'image/png');

@@ -269,3 +262,3 @@ ensureContentType('jpg', 'image/jpeg');

if (numHtmls) {
DEBUG && debug_1.default.debug('Completing [Content_Types].xml for HTML...');
debug_1.logger.debug('Completing [Content_Types].xml for HTML...');
ensureContentType('html', 'text/html');

@@ -276,9 +269,6 @@ }

}
// ---------------------------------------------------------
// Zip the results
// ---------------------------------------------------------
DEBUG && debug_1.default.debug('Zipping...');
debug_1.logger.debug('Zipping...');
return [4 /*yield*/, zip_1.zipSave(zip)];
case 22:
output = _a.sent();
case 19:
output = _b.sent();
return [2 /*return*/, output];

@@ -289,2 +279,67 @@ }

}
/**
* Lists all the commands in a docx template.
*
* example:
* ```js
* const template_buffer = fs.readFileSync('template.docx');
* const commands = await listCommands(template_buffer, ['{', '}']);
* // `commands` will contain something like:
* [
* { raw: 'INS some_variable', code: 'some_variable', type: 'INS' },
* { raw: 'IMAGE svgImgFile()', code: 'svgImgFile()', type: 'IMAGE' },
* ]
* ```
*
* @param template the docx template as a Buffer-like object
* @param delimiter the command delimiter (defaults to ['+++', '+++'])
*/
function listCommands(template, delimiter) {
return __awaiter(this, void 0, void 0, function () {
var opts, jsTemplate, prepped, commands;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
opts = {
cmdDelimiter: getCmdDelimiter(delimiter),
// Otherwise unused but mandatory options
literalXmlDelimiter: DEFAULT_LITERAL_XML_DELIMITER,
processLineBreaks: true,
noSandbox: false,
additionalJsContext: {},
failFast: false,
rejectNullish: false,
};
return [4 /*yield*/, parseTemplate(template)];
case 1:
jsTemplate = (_a.sent()).jsTemplate;
debug_1.logger.debug('Preprocessing template...');
prepped = preprocessTemplate_1.default(jsTemplate, opts.cmdDelimiter);
commands = [];
return [4 /*yield*/, processTemplate_1.walkTemplate(undefined, prepped, opts, function (data, node, ctx) { return __awaiter(_this, void 0, void 0, function () {
var raw, _a, cmdName, code, type;
return __generator(this, function (_b) {
raw = processTemplate_1.getCommand(ctx.cmd, ctx.shorthands);
ctx.cmd = ''; // flush the context
_a = processTemplate_1.splitCommand(raw), cmdName = _a.cmdName, code = _a.cmdRest;
type = cmdName;
if (type != null && type !== 'CMD_NODE') {
commands.push({
raw: raw,
type: type,
code: code,
});
}
return [2 /*return*/, undefined];
});
}); })];
case 2:
_a.sent();
return [2 /*return*/, commands];
}
});
});
}
exports.listCommands = listCommands;
function readContentTypes(zip) {

@@ -335,6 +390,6 @@ return __awaiter(this, void 0, void 0, function () {

case 0:
DEBUG && debug_1.default.debug("Processing images for " + documentComponent + "...");
debug_1.logger.debug("Processing images for " + documentComponent + "...");
imageIds = Object.keys(images);
if (!imageIds.length) return [3 /*break*/, 2];
DEBUG && debug_1.default.debug('Completing document.xml.rels...');
debug_1.logger.debug('Completing document.xml.rels...');
relsPath = templatePath + "/_rels/" + documentComponent + ".rels";

@@ -348,3 +403,3 @@ return [4 /*yield*/, getRelsFromZip(zip, relsPath)];

imgName = "template_" + documentComponent + "_image" + (i + 1) + extension;
DEBUG && debug_1.default.debug("Writing image " + imageId + " (" + imgName + ")...");
debug_1.logger.debug("Writing image " + imageId + " (" + imgName + ")...");
imgPath = templatePath + "/media/" + imgName;

@@ -380,6 +435,6 @@ if (typeof imgData === 'string') {

case 0:
DEBUG && debug_1.default.debug("Processing links for " + documentComponent + "...");
debug_1.logger.debug("Processing links for " + documentComponent + "...");
linkIds = Object.keys(links);
if (!linkIds.length) return [3 /*break*/, 2];
DEBUG && debug_1.default.debug('Completing document.xml.rels...');
debug_1.logger.debug('Completing document.xml.rels...');
relsPath = templatePath + "/_rels/" + documentComponent + ".rels";

@@ -413,7 +468,7 @@ return [4 /*yield*/, getRelsFromZip(zip, relsPath)];

case 0:
DEBUG && debug_1.default.debug("Processing htmls for " + documentComponent + "...");
debug_1.logger.debug("Processing htmls for " + documentComponent + "...");
htmlIds = Object.keys(htmls);
if (!htmlIds.length) return [3 /*break*/, 2];
// Process rels
DEBUG && debug_1.default.debug("Completing document.xml.rels...");
debug_1.logger.debug("Completing document.xml.rels...");
htmlFiles = [];

@@ -428,3 +483,3 @@ relsPath = templatePath + "/_rels/" + documentComponent + ".rels";

htmlName = "template_" + documentComponent + "_" + htmlId + ".html";
DEBUG && debug_1.default.debug("Writing html " + htmlId + " (" + htmlName + ")...");
debug_1.logger.debug("Writing html " + htmlId + " (" + htmlName + ")...");
htmlPath = templatePath + "/" + htmlName;

@@ -472,5 +527,2 @@ htmlFiles.push("/" + htmlPath);

};
// ==========================================
// Public API
// ==========================================
exports.default = createReport;

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

import { Node, CreateReportOptions } from './types';
declare const preprocessTemplate: (template: Node, options: CreateReportOptions) => Node;
import { Node } from './types';
declare const preprocessTemplate: (template: Node, delimiter: [string, string]) => Node;
export default preprocessTemplate;

@@ -7,4 +7,3 @@ "use strict";

// at the starting node
var preprocessTemplate = function (template, options) {
var delimiter = options.cmdDelimiter;
var preprocessTemplate = function (template, delimiter) {
var node = template;

@@ -11,0 +10,0 @@ var fCmd = false;

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

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

@@ -13,3 +13,10 @@ status: 'success';

};
declare const produceJsReport: (data: ReportData | undefined, template: Node, options: CreateReportOptions) => Promise<ReportOutput>;
export { extractQuery, produceJsReport };
export declare function produceJsReport(data: ReportData | undefined, template: Node, options: CreateReportOptions): Promise<ReportOutput>;
export declare function walkTemplate(data: ReportData | undefined, template: Node, options: CreateReportOptions, processor: CommandProcessor): Promise<ReportOutput>;
declare type CommandProcessor = (data: ReportData | undefined, node: Node, ctx: Context) => Promise<undefined | string | Error>;
export declare function getCommand(command: string, shorthands: Context['shorthands']): string;
export declare function splitCommand(cmd: string): {
cmdName: string | undefined;
cmdRest: string;
};
export {};

@@ -39,324 +39,334 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.produceJsReport = exports.extractQuery = void 0;
exports.splitCommand = exports.getCommand = exports.walkTemplate = exports.produceJsReport = exports.extractQuery = void 0;
var reportUtils_1 = require("./reportUtils");
var jsSandbox_1 = require("./jsSandbox");
var types_1 = require("./types");
var errors_1 = require("./errors");
var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;
var log = DEBUG ? require('./debug').mainStory : null;
var gCntIf = 0;
var debug_1 = require("./debug");
function newContext(options) {
return {
gCntIf: 0,
level: 1,
fCmd: false,
cmd: '',
fSeekQuery: false,
buffers: {
'w:p': { text: '', cmds: '', fInsertedText: false },
'w:tr': { text: '', cmds: '', fInsertedText: false },
},
imageId: 0,
images: {},
linkId: 0,
links: {},
htmlId: 0,
htmls: {},
vars: {},
loops: [],
fJump: false,
shorthands: {},
options: options,
};
}
// Go through the document until the query string is found (normally at the beginning)
var extractQuery = function (template, options) { return __awaiter(void 0, void 0, void 0, function () {
var ctx, nodeIn, fFound, parent_1, nextSibling, parent_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
ctx = {
fCmd: false,
cmd: '',
fSeekQuery: true,
query: null,
loops: [],
options: options,
};
nodeIn = template;
_a.label = 1;
case 1:
if (!true) return [3 /*break*/, 4];
// Move down
if (nodeIn._children.length)
nodeIn = nodeIn._children[0];
else {
fFound = false;
while (nodeIn._parent != null) {
parent_1 = nodeIn._parent;
nextSibling = reportUtils_1.getNextSibling(nodeIn);
if (nextSibling) {
nodeIn = nextSibling;
fFound = true;
break;
function extractQuery(template, options) {
return __awaiter(this, void 0, void 0, function () {
var ctx, nodeIn, fFound, parent_1, nextSibling, parent_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
ctx = newContext(options);
// ensure no command will be processed, except QUERY
ctx.fSeekQuery = true;
nodeIn = template;
_a.label = 1;
case 1:
if (!true) return [3 /*break*/, 4];
// Move down
if (nodeIn._children.length)
nodeIn = nodeIn._children[0];
else {
fFound = false;
while (nodeIn._parent != null) {
parent_1 = nodeIn._parent;
nextSibling = reportUtils_1.getNextSibling(nodeIn);
if (nextSibling) {
nodeIn = nextSibling;
fFound = true;
break;
}
nodeIn = parent_1;
}
nodeIn = parent_1;
if (!fFound)
return [3 /*break*/, 4];
}
if (!fFound)
if (!nodeIn)
return [3 /*break*/, 4];
}
if (!nodeIn)
return [3 /*break*/, 4];
parent_2 = nodeIn._parent;
if (!(nodeIn._fTextNode &&
parent_2 &&
!parent_2._fTextNode && // Flow, don't complain
parent_2._tag === 'w:t')) return [3 /*break*/, 3];
return [4 /*yield*/, processText(null, nodeIn, ctx)];
case 2:
_a.sent();
_a.label = 3;
case 3:
if (ctx.query != null)
return [3 /*break*/, 4];
return [3 /*break*/, 1];
case 4: return [2 /*return*/, ctx.query];
}
parent_2 = nodeIn._parent;
if (!(nodeIn._fTextNode &&
parent_2 &&
!parent_2._fTextNode && // Flow, don't complain
parent_2._tag === 'w:t')) return [3 /*break*/, 3];
return [4 /*yield*/, processText(null, nodeIn, ctx, processCmd)];
case 2:
_a.sent();
_a.label = 3;
case 3:
if (ctx.query != null)
return [3 /*break*/, 4];
return [3 /*break*/, 1];
case 4: return [2 /*return*/, ctx.query];
}
});
});
}); };
}
exports.extractQuery = extractQuery;
var produceJsReport = function (data, template, options) { return __awaiter(void 0, void 0, void 0, function () {
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:
out = reportUtils_1.cloneNodeWithoutChildren(template);
ctx = {
level: 1,
fCmd: false,
cmd: '',
fSeekQuery: false,
buffers: {
'w:p': { text: '', cmds: '', fInsertedText: false },
'w:tr': { text: '', cmds: '', fInsertedText: false },
},
imageId: 0,
images: {},
linkId: 0,
links: {},
htmlId: 0,
htmls: {},
vars: {},
loops: [],
fJump: false,
shorthands: {},
options: options,
};
nodeIn = template;
nodeOut = out;
deltaJump = 0;
errors = [];
_a.label = 1;
case 1:
if (!true) return [3 /*break*/, 5];
curLoop = reportUtils_1.getCurLoop(ctx);
nextSibling = void 0;
// =============================================
// Move input node pointer
// =============================================
if (ctx.fJump) {
if (!curLoop)
throw new errors_1.InternalError();
refNode = curLoop.refNode, refNodeLevel = curLoop.refNodeLevel;
// DEBUG &&
// log.debug(`Jumping to level ${refNodeLevel}...`, {
// attach: cloneNodeForLogging(refNode),
// });
deltaJump = ctx.level - refNodeLevel;
nodeIn = refNode;
ctx.level = refNodeLevel;
ctx.fJump = false;
move = 'JUMP';
// Down (only if he haven't just moved up)
}
else if (nodeIn._children.length && move !== 'UP') {
nodeIn = nodeIn._children[0];
ctx.level += 1;
move = 'DOWN';
// Sideways
}
else if ((nextSibling = reportUtils_1.getNextSibling(nodeIn))) {
nodeIn = nextSibling;
move = 'SIDE';
// Up
}
else {
parent_3 = nodeIn._parent;
if (parent_3 == null)
return [3 /*break*/, 5];
nodeIn = parent_3;
ctx.level -= 1;
move = 'UP';
}
// DEBUG &&
// log.debug(
// `Next node [${chalk.green.bold(move)}, level ${chalk.dim(ctx.level)}]`,
// { attach: cloneNodeForLogging(nodeIn) }
// );
// =============================================
// Process input node
// =============================================
// Delete the last generated output node in several special cases
// --------------------------------------------------------------
if (move !== 'DOWN') {
tag = nodeOut._fTextNode ? null : nodeOut._tag;
fRemoveNode = false;
// Delete last generated output node if we're skipping nodes due to an empty FOR loop
if ((tag === 'w:p' || tag === 'w:tbl' || tag === 'w:tr') &&
reportUtils_1.isLoopExploring(ctx)) {
fRemoveNode = true;
// Delete last generated output node if the user inserted a paragraph
// (or table row) with just a command
function produceJsReport(data, template, options) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, walkTemplate(data, template, options, processCmd)];
});
});
}
exports.produceJsReport = produceJsReport;
function walkTemplate(data, template, options, processor) {
return __awaiter(this, void 0, void 0, function () {
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:
out = reportUtils_1.cloneNodeWithoutChildren(template);
ctx = newContext(options);
nodeIn = template;
nodeOut = out;
deltaJump = 0;
errors = [];
_a.label = 1;
case 1:
if (!true) return [3 /*break*/, 5];
curLoop = reportUtils_1.getCurLoop(ctx);
nextSibling = void 0;
// =============================================
// Move input node pointer
// =============================================
if (ctx.fJump) {
if (!curLoop)
throw new errors_1.InternalError();
refNode = curLoop.refNode, refNodeLevel = curLoop.refNodeLevel;
//
// logger.debug(`Jumping to level ${refNodeLevel}...`, {
// attach: cloneNodeForLogging(refNode),
// });
deltaJump = ctx.level - refNodeLevel;
nodeIn = refNode;
ctx.level = refNodeLevel;
ctx.fJump = false;
move = 'JUMP';
// Down (only if he haven't just moved up)
}
else if (tag === 'w:p' || tag === 'w:tr') {
buffers = ctx.buffers[tag];
fRemoveNode =
buffers.text === '' && buffers.cmds !== '' && !buffers.fInsertedText;
else if (nodeIn._children.length && move !== 'UP') {
nodeIn = nodeIn._children[0];
ctx.level += 1;
move = 'DOWN';
// Sideways
}
// Execute removal, if needed. The node will no longer be part of the output, but
// the parent will be accessible from the child (so that we can still move up the tree)
if (fRemoveNode && nodeOut._parent != null) {
nodeOut._parent._children.pop();
else if ((nextSibling = reportUtils_1.getNextSibling(nodeIn))) {
nodeIn = nextSibling;
move = 'SIDE';
// Up
}
}
// Handle an UP movement
// ---------------------
if (move === 'UP') {
// Loop exploring? Update the reference node for the current loop
if (reportUtils_1.isLoopExploring(ctx) &&
curLoop && // Flow, don't complain
nodeIn === curLoop.refNode._parent) {
curLoop.refNode = nodeIn;
curLoop.refNodeLevel -= 1;
// DEBUG &&
// log.debug(`Updated loop '${curLoop.varName}' refNode:`, {
// attach: cloneNodeForLogging(nodeIn),
// });
else {
parent_3 = nodeIn._parent;
if (parent_3 == null)
return [3 /*break*/, 5];
nodeIn = parent_3;
ctx.level -= 1;
move = 'UP';
}
nodeOutParent = nodeOut._parent;
if (nodeOutParent == null)
throw new errors_1.InternalError();
// Execute the move in the output tree
nodeOut = nodeOutParent;
// If an image was generated, replace the parent `w:t` node with
// the image node
if (ctx.pendingImageNode &&
!nodeOut._fTextNode && // Flow-prevention
nodeOut._tag === 'w:t') {
imgNode = ctx.pendingImageNode;
parent_4 = nodeOut._parent;
if (parent_4) {
imgNode._parent = parent_4;
parent_4._children.pop();
parent_4._children.push(imgNode);
// Prevent containing paragraph or table row from being removed
ctx.buffers['w:p'].fInsertedText = true;
ctx.buffers['w:tr'].fInsertedText = true;
//
// logger.debug(
// `Next node [${chalk.green.bold(move)}, level ${chalk.dim(ctx.level)}]`,
// { attach: cloneNodeForLogging(nodeIn) }
// );
// =============================================
// Process input node
// =============================================
// Delete the last generated output node in several special cases
// --------------------------------------------------------------
if (move !== 'DOWN') {
tag = nodeOut._fTextNode ? null : nodeOut._tag;
fRemoveNode = false;
// Delete last generated output node if we're skipping nodes due to an empty FOR loop
if ((tag === 'w:p' || tag === 'w:tbl' || tag === 'w:tr') &&
reportUtils_1.isLoopExploring(ctx)) {
fRemoveNode = true;
// Delete last generated output node if the user inserted a paragraph
// (or table row) with just a command
}
delete ctx.pendingImageNode;
}
// If a link was generated, replace the parent `w:r` node with
// the link node
if (ctx.pendingLinkNode &&
!nodeOut._fTextNode && // Flow-prevention
nodeOut._tag === 'w:r') {
linkNode = ctx.pendingLinkNode;
parent_5 = nodeOut._parent;
if (parent_5) {
linkNode._parent = parent_5;
parent_5._children.pop();
parent_5._children.push(linkNode);
// Prevent containing paragraph or table row from being removed
ctx.buffers['w:p'].fInsertedText = true;
ctx.buffers['w:tr'].fInsertedText = true;
else if (tag === 'w:p' || tag === 'w:tr') {
buffers = ctx.buffers[tag];
fRemoveNode =
buffers.text === '' && buffers.cmds !== '' && !buffers.fInsertedText;
}
delete ctx.pendingLinkNode;
// Execute removal, if needed. The node will no longer be part of the output, but
// the parent will be accessible from the child (so that we can still move up the tree)
if (fRemoveNode && nodeOut._parent != null) {
nodeOut._parent._children.pop();
}
}
// If a html page was generated, replace the parent `w:p` node with
// the html node
if (ctx.pendingHtmlNode &&
!nodeOut._fTextNode && // Flow-prevention
nodeOut._tag === 'w:p') {
htmlNode = ctx.pendingHtmlNode;
parent_6 = nodeOut._parent;
if (parent_6) {
htmlNode._parent = parent_6;
parent_6._children.pop();
parent_6._children.push(htmlNode);
// Prevent containing paragraph or table row from being removed
ctx.buffers['w:p'].fInsertedText = true;
ctx.buffers['w:tr'].fInsertedText = true;
// Handle an UP movement
// ---------------------
if (move === 'UP') {
// Loop exploring? Update the reference node for the current loop
if (reportUtils_1.isLoopExploring(ctx) &&
curLoop && // Flow, don't complain
nodeIn === curLoop.refNode._parent) {
curLoop.refNode = nodeIn;
curLoop.refNodeLevel -= 1;
//
// logger.debug(`Updated loop '${curLoop.varName}' refNode:`, {
// attach: cloneNodeForLogging(nodeIn),
// });
}
delete ctx.pendingHtmlNode;
nodeOutParent = nodeOut._parent;
if (nodeOutParent == null)
throw new errors_1.InternalError();
// Execute the move in the output tree
nodeOut = nodeOutParent;
// If an image was generated, replace the parent `w:t` node with
// the image node
if (ctx.pendingImageNode &&
!nodeOut._fTextNode && // Flow-prevention
nodeOut._tag === 'w:t') {
imgNode = ctx.pendingImageNode;
parent_4 = nodeOut._parent;
if (parent_4) {
imgNode._parent = parent_4;
parent_4._children.pop();
parent_4._children.push(imgNode);
// Prevent containing paragraph or table row from being removed
ctx.buffers['w:p'].fInsertedText = true;
ctx.buffers['w:tr'].fInsertedText = true;
}
delete ctx.pendingImageNode;
}
// If a link was generated, replace the parent `w:r` node with
// the link node
if (ctx.pendingLinkNode &&
!nodeOut._fTextNode && // Flow-prevention
nodeOut._tag === 'w:r') {
linkNode = ctx.pendingLinkNode;
parent_5 = nodeOut._parent;
if (parent_5) {
linkNode._parent = parent_5;
parent_5._children.pop();
parent_5._children.push(linkNode);
// Prevent containing paragraph or table row from being removed
ctx.buffers['w:p'].fInsertedText = true;
ctx.buffers['w:tr'].fInsertedText = true;
}
delete ctx.pendingLinkNode;
}
// If a html page was generated, replace the parent `w:p` node with
// the html node
if (ctx.pendingHtmlNode &&
!nodeOut._fTextNode && // Flow-prevention
nodeOut._tag === 'w:p') {
htmlNode = ctx.pendingHtmlNode;
parent_6 = nodeOut._parent;
if (parent_6) {
htmlNode._parent = parent_6;
parent_6._children.pop();
parent_6._children.push(htmlNode);
// Prevent containing paragraph or table row from being removed
ctx.buffers['w:p'].fInsertedText = true;
ctx.buffers['w:tr'].fInsertedText = true;
}
delete ctx.pendingHtmlNode;
}
// `w:tc` nodes shouldn't be left with no `w:p` children; if that's the
// case, add an empty `w:p` inside
if (!nodeOut._fTextNode && // Flow-prevention
nodeOut._tag === 'w:tc' &&
!nodeOut._children.filter(function (o) { return !o._fTextNode && o._tag === 'w:p'; }).length) {
nodeOut._children.push({
_parent: nodeOut,
_children: [],
_fTextNode: false,
_tag: 'w:p',
_attrs: {},
});
}
// Save latest `w:rPr` node that was visited (for LINK properties)
if (!nodeIn._fTextNode && nodeIn._tag === 'w:rPr') {
ctx.textRunPropsNode = nodeIn;
}
if (!nodeIn._fTextNode && nodeIn._tag === 'w:r') {
delete ctx.textRunPropsNode;
}
}
// `w:tc` nodes shouldn't be left with no `w:p` children; if that's the
// case, add an empty `w:p` inside
if (!nodeOut._fTextNode && // Flow-prevention
nodeOut._tag === 'w:tc' &&
!nodeOut._children.filter(function (o) { return !o._fTextNode && o._tag === 'w:p'; }).length) {
nodeOut._children.push({
_parent: nodeOut,
_children: [],
_fTextNode: false,
_tag: 'w:p',
_attrs: {},
});
}
// Save latest `w:rPr` node that was visited (for LINK properties)
if (!nodeIn._fTextNode && nodeIn._tag === 'w:rPr') {
ctx.textRunPropsNode = nodeIn;
}
if (!nodeIn._fTextNode && nodeIn._tag === 'w:r') {
delete ctx.textRunPropsNode;
}
}
if (!(move === 'DOWN' || move === 'SIDE')) return [3 /*break*/, 4];
// Move nodeOut to point to the new node's parent
if (move === 'SIDE') {
if (nodeOut._parent == null)
throw new errors_1.InternalError();
nodeOut = nodeOut._parent;
}
tag = nodeIn._fTextNode ? null : nodeIn._tag;
if (tag === 'w:p' || tag === 'w:tr') {
ctx.buffers[tag] = { text: '', cmds: '', fInsertedText: false };
}
newNode = reportUtils_1.cloneNodeWithoutChildren(nodeIn);
newNode._parent = nodeOut;
nodeOut._children.push(newNode);
parent_7 = nodeIn._parent;
if (!(nodeIn._fTextNode &&
parent_7 &&
!parent_7._fTextNode &&
parent_7._tag === 'w:t')) return [3 /*break*/, 3];
return [4 /*yield*/, processText(data, nodeIn, ctx)];
case 2:
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;
_a.label = 4;
case 4:
// Correct output tree level in case of a JUMP
// -------------------------------------------
if (move === 'JUMP') {
while (deltaJump > 0) {
if (!(move === 'DOWN' || move === 'SIDE')) return [3 /*break*/, 4];
// Move nodeOut to point to the new node's parent
if (move === 'SIDE') {
if (nodeOut._parent == null)
throw new errors_1.InternalError();
nodeOut = nodeOut._parent;
deltaJump -= 1;
}
}
return [3 /*break*/, 1];
case 5:
if (errors.length > 0)
tag = nodeIn._fTextNode ? null : nodeIn._tag;
if (tag === 'w:p' || tag === 'w:tr') {
ctx.buffers[tag] = { text: '', cmds: '', fInsertedText: false };
}
newNode = reportUtils_1.cloneNodeWithoutChildren(nodeIn);
newNode._parent = nodeOut;
nodeOut._children.push(newNode);
parent_7 = nodeIn._parent;
if (!(nodeIn._fTextNode &&
parent_7 &&
!parent_7._fTextNode &&
parent_7._tag === 'w:t')) return [3 /*break*/, 3];
return [4 /*yield*/, processText(data, nodeIn, ctx, processor)];
case 2:
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;
_a.label = 4;
case 4:
// Correct output tree level in case of a JUMP
// -------------------------------------------
if (move === 'JUMP') {
while (deltaJump > 0) {
if (nodeOut._parent == null)
throw new errors_1.InternalError();
nodeOut = nodeOut._parent;
deltaJump -= 1;
}
}
return [3 /*break*/, 1];
case 5:
if (errors.length > 0)
return [2 /*return*/, {
status: 'errors',
errors: errors,
}];
return [2 /*return*/, {
status: 'errors',
errors: errors,
status: 'success',
report: out,
images: ctx.images,
links: ctx.links,
htmls: ctx.htmls,
}];
return [2 /*return*/, {
status: 'success',
report: out,
images: ctx.images,
links: ctx.links,
htmls: ctx.htmls,
}];
}
}
});
});
}); };
exports.produceJsReport = produceJsReport;
var processText = function (data, node, ctx) { return __awaiter(void 0, void 0, void 0, function () {
}
exports.walkTemplate = walkTemplate;
var processText = function (data, node, ctx, onCommand) { return __awaiter(void 0, void 0, void 0, function () {
var _a, cmdDelimiter, failFast, text, segments, outText, errors, idx, segment, cmdResultText;

@@ -384,3 +394,3 @@ return __generator(this, function (_b) {

segment = segments[idx];
// DEBUG && log.debug(`Token: '${segment}' (${ctx.fCmd})`);
// logger.debug(`Token: '${segment}' (${ctx.fCmd})`);
if (ctx.fCmd)

@@ -393,3 +403,3 @@ ctx.cmd += segment;

if (!ctx.fCmd) return [3 /*break*/, 3];
return [4 /*yield*/, processCmd(data, node, ctx)];
return [4 /*yield*/, onCommand(data, node, ctx)];
case 2:

@@ -429,18 +439,13 @@ cmdResultText = _b.sent();

var processCmd = function (data, node, ctx) { return __awaiter(void 0, void 0, void 0, function () {
var cmd, cmdNameMatch, cmdName, cmdRest, aliasMatch, aliasName, fullCmd, result, str, literalXmlDelimiter, img, e_1, pars, html, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
var cmd, _a, cmdName, cmdRest, aliasMatch, aliasName, fullCmd, result, str, literalXmlDelimiter, img, e_1, pars, html, err_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
cmd = getCommand(ctx);
DEBUG && log.debug("Processing cmd: " + cmd);
_a.label = 1;
cmd = getCommand(ctx.cmd, ctx.shorthands);
ctx.cmd = ''; // flush the context
debug_1.logger.debug("Processing cmd: " + cmd);
_b.label = 1;
case 1:
_a.trys.push([1, 28, , 29]);
cmdNameMatch = /^(\S+)\s*/.exec(cmd);
cmdName = void 0;
cmdRest = '';
if (cmdNameMatch != null) {
cmdName = cmdNameMatch[1].toUpperCase();
cmdRest = cmd.slice(cmdName.length).trim();
}
_b.trys.push([1, 28, , 29]);
_a = splitCommand(cmd), cmdName = _a.cmdName, cmdRest = _a.cmdRest;
// Seeking query?

@@ -462,3 +467,3 @@ if (ctx.fSeekQuery) {

ctx.shorthands[aliasName] = fullCmd;
DEBUG && log.debug("Defined alias '" + aliasName + "' for: " + fullCmd);
debug_1.logger.debug("Defined alias '" + aliasName + "' for: " + fullCmd);
return [3 /*break*/, 27];

@@ -469,3 +474,3 @@ case 3:

case 4:
_a.sent();
_b.sent();
return [3 /*break*/, 27];

@@ -481,3 +486,3 @@ case 5:

case 7:
result = _a.sent();
result = _b.sent();
if (result == null) {

@@ -501,4 +506,4 @@ if (ctx.options.rejectNullish) {

case 10:
_a.sent();
_a.label = 11;
_b.sent();
_b.label = 11;
case 11: return [3 /*break*/, 27];

@@ -510,3 +515,3 @@ case 12:

case 13:
img = _a.sent();
img = _b.sent();
if (ctx.options.rejectNullish && img == null) {

@@ -516,11 +521,11 @@ throw new errors_1.NullishCommandResultError(cmdRest);

if (!(img != null)) return [3 /*break*/, 17];
_a.label = 14;
_b.label = 14;
case 14:
_a.trys.push([14, 16, , 17]);
_b.trys.push([14, 16, , 17]);
return [4 /*yield*/, processImage(ctx, img)];
case 15:
_a.sent();
_b.sent();
return [3 /*break*/, 17];
case 16:
e_1 = _a.sent();
e_1 = _b.sent();
throw new errors_1.ImageError(e_1.message, cmd);

@@ -533,3 +538,3 @@ case 17: return [3 /*break*/, 27];

case 19:
pars = _a.sent();
pars = _b.sent();
if (ctx.options.rejectNullish && pars == null) {

@@ -541,4 +546,4 @@ throw new errors_1.NullishCommandResultError(cmdRest);

case 20:
_a.sent();
_a.label = 21;
_b.sent();
_b.label = 21;
case 21: return [3 /*break*/, 27];

@@ -550,3 +555,3 @@ case 22:

case 23:
html = _a.sent();
html = _b.sent();
if (ctx.options.rejectNullish && html == null) {

@@ -558,4 +563,4 @@ throw new errors_1.NullishCommandResultError(cmdRest);

case 24:
_a.sent();
_a.label = 25;
_b.sent();
_b.label = 25;
case 25: return [3 /*break*/, 27];

@@ -565,3 +570,3 @@ case 26: throw new errors_1.CommandSyntaxError(cmd);

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

@@ -572,28 +577,14 @@ case 29: return [2 /*return*/];

}); };
var builtInCommands = [
'QUERY',
'CMD_NODE',
'ALIAS',
'FOR',
'END-FOR',
'IF',
'END-IF',
'INS',
'EXEC',
'IMAGE',
'LINK',
'HTML',
];
var builtInRegexes = builtInCommands.map(function (word) { return new RegExp("^" + word + "\\b"); });
var builtInRegexes = types_1.BUILT_IN_COMMANDS.map(function (word) { return new RegExp("^" + word + "\\b"); });
var notBuiltIns = function (cmd) {
return !builtInRegexes.some(function (r) { return r.test(cmd.toUpperCase()); });
};
var getCommand = function (ctx) {
var cmd = ctx.cmd.trim();
function getCommand(command, shorthands) {
var cmd = command.trim();
if (cmd[0] === '*') {
var aliasName = cmd.slice(1).trim();
if (!ctx.shorthands[aliasName])
if (!shorthands[aliasName])
throw new errors_1.InvalidCommandError('Unknown alias', cmd);
cmd = ctx.shorthands[aliasName];
DEBUG && log.debug("Alias for: " + cmd);
cmd = shorthands[aliasName];
debug_1.logger.debug("Alias for: " + cmd);
}

@@ -609,5 +600,17 @@ else if (cmd[0] === '=') {

}
ctx.cmd = '';
return cmd.trim();
};
}
exports.getCommand = getCommand;
function splitCommand(cmd) {
// Extract command name
var cmdNameMatch = /^(\S+)\s*/.exec(cmd);
var cmdName;
var cmdRest = '';
if (cmdNameMatch != null) {
cmdName = cmdNameMatch[1].toUpperCase();
cmdRest = cmd.slice(cmdName.length).trim();
}
return { cmdName: cmdName, cmdRest: cmdRest };
}
exports.splitCommand = splitCommand;
// ==========================================

@@ -624,4 +627,4 @@ // Individual commands

if (!node._ifName) {
node._ifName = "__if_" + gCntIf;
gCntIf += 1;
node._ifName = "__if_" + ctx.gCntIf;
ctx.gCntIf += 1;
}

@@ -693,4 +696,3 @@ varName = node._ifName;

if (ctx.loops.find(function (o) { return o.varName === varName; }) == null) {
DEBUG &&
log.debug("Ignoring " + cmd + " (" + varName + ", but we're expecting " + curLoop.varName + ")");
debug_1.logger.debug("Ignoring " + cmd + " (" + varName + ", but we're expecting " + curLoop.varName + ")");
return;

@@ -697,0 +699,0 @@ }

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

var errors_1 = require("./errors");
var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;
var log = DEBUG ? require('./debug').mainStory : null;
var debug_1 = require("./debug");
// ==========================================

@@ -108,4 +107,2 @@ // Nodes and trees

var logLoop = function (loops) {
if (!DEBUG)
return;
if (!loops.length)

@@ -116,3 +113,3 @@ return;

var idxStr = idx >= 0 ? idx + 1 : 'EXPLORATION';
log.debug((isIf ? 'IF' : 'FOR') + " loop " +
debug_1.logger.debug((isIf ? 'IF' : 'FOR') + " loop " +
("on " + level + ":" + varName) +

@@ -119,0 +116,0 @@ (idxStr + "/" + loopOver.length));

@@ -101,2 +101,3 @@ /// <reference types="node" />

export declare type Context = {
gCntIf: number;
level: number;

@@ -174,2 +175,9 @@ fCmd: boolean;

};
export declare type CommandSummary = {
raw: string;
type: BuiltInCommand;
code: string;
};
export declare type BuiltInCommand = typeof BUILT_IN_COMMANDS[number];
export declare const BUILT_IN_COMMANDS: readonly ["QUERY", "CMD_NODE", "ALIAS", "FOR", "END-FOR", "IF", "END-IF", "INS", "EXEC", "IMAGE", "LINK", "HTML"];
export {};

@@ -5,1 +5,16 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.BUILT_IN_COMMANDS = void 0;
exports.BUILT_IN_COMMANDS = [
'QUERY',
'CMD_NODE',
'ALIAS',
'FOR',
'END-FOR',
'IF',
'END-IF',
'INS',
'EXEC',
'IMAGE',
'LINK',
'HTML',
];

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

var sax_1 = __importDefault(require("sax"));
var DEBUG = process.env.DEBUG_DOCX_TEMPLATES;
var log = DEBUG ? require('./debug').mainStory : null;
var debug_1 = require("./debug");
var parseXml = function (templateXml) {

@@ -50,3 +49,3 @@ var parser = sax_1.default.parser(true, {

parser.onend = function () {
DEBUG && log.debug("Number of XML elements: " + numXmlElements);
debug_1.logger.debug("Number of XML elements: " + numXmlElements);
resolve(template);

@@ -53,0 +52,0 @@ };

{
"name": "docx-templates",
"version": "4.2.0",
"version": "4.3.0",
"description": "Template-based docx report creation",

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

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

@@ -48,4 +48,4 @@ "timm": "^1.6.2"

"devDependencies": {
"@types/jest": "^25.2.3",
"@types/node": "^13.13.2",
"@types/jest": "^26.0.0",
"@types/node": "^14.0.13",
"@types/qrcode": "^1.3.4",

@@ -56,3 +56,3 @@ "@types/sax": "^1.2.1",

"coveralls": "^3.0.13",
"eslint": "^6.8.0",
"eslint": "^7.3.1",
"eslint-config-prettier": "^6.11.0",

@@ -63,3 +63,3 @@ "eslint-plugin-import": "^2.20.2",

"jest": "^26.0.1",
"mockdate": "^2.0.5",
"mockdate": "^3.0.2",
"nyc": "^15.0.1",

@@ -66,0 +66,0 @@ "oao": "^1.8.0",

@@ -345,2 +345,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)

+++HTML `
<meta charset="UTF-8">
<body>

@@ -474,2 +475,16 @@ <h1>${$film.title}</h1>

# Inspecting templates
The `listCommands` function lets you list all the commands in a docx template using the same parser as `createReport`.
```typescript
const template_buffer = fs.readFileSync('template.docx');
const commands = await listCommands(template_buffer, ['{', '}']);
// `commands` will contain something like:
[
{ raw: 'INS some_variable', code: 'some_variable', type: 'INS' },
{ raw: 'IMAGE svgImgFile()', code: 'svgImgFile()', type: 'IMAGE' },
]
```
# Performance & security

@@ -476,0 +491,0 @@

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