type Buffer = ArrayBufferLike; interface QualifiedName { name: string; prefix: string; local: string; uri: string; } interface QualifiedAttribute extends QualifiedName { value: string; } type Node = TextNode | NonTextNode; type BaseNode = { _parent?: Node; _children: Array; _ifName?: string; }; type TextNode = BaseNode & { _fTextNode: true; _text: string; }; type NonTextNode = BaseNode & { _fTextNode: false; _tag: string; _attrs: { [key: string]: QualifiedAttribute | string; } & { Extension?: string; ContentType?: string; PartName?: string; }; }; type ReportData = any; type QueryResolver = (query: string | undefined, queryVars: any) => ReportData | Promise; type ErrorHandler = (e: Error, raw_code?: string) => any; type RunJSFunc = (o: { sandbox: SandBox; ctx: Context; }) => { modifiedSandbox: SandBox; result: unknown; }; type UserOptions = { /** * Docx file template as a Uint8Array (or e.g. ArrayBuffer or NodeJS Buffer). */ template: Uint8Array; /** * 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]; /** * The delimiter that's used to indicate literal XML that should be inserted into the docx XML tree as-is. Defaults to `||`. */ 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; /** * 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`. */ rejectNullish?: boolean; /** * Custom error handler to catch any errors that may occur evaluating commands in the template. The value returned from this handler will be inserted into the template instead. */ errorHandler?: ErrorHandler; /** * MS Word usually autocorrects JS string literal quotes with unicode 'smart' quotes ('curly' quotes). E.g. 'aubergine' -> ‘aubergine’. * This causes an error when evaluating commands containing these smart quotes, as they are not valid JavaScript. * If you set fixSmartQuotes to 'true', these smart quotes will automatically get replaced with straight quotes (') before command evaluation. * Defaults to false. */ fixSmartQuotes?: boolean; /** * Use the new way of injecting line breaks from command results (only applies when `processLineBreaks` is `true`) * which has better results in LibreOffice and Google Drive. * (Default: false) */ processLineBreaksAsNewText?: boolean; /** * Maximum loop iterations allowed when walking through the template. * You can increase this to generate reports with large amount of FOR loop elements. * Tip: You can disable infinite loop protection by using the `Infinity` constant. * This may be useful if you implement a process timeout instead. * (Default: 1,000,000) */ maximumWalkingDepth?: number; }; type CreateReportOptions = { cmdDelimiter: [string, string]; literalXmlDelimiter: string; processLineBreaks: boolean; noSandbox: boolean; runJs?: RunJSFunc; additionalJsContext: Object; failFast: boolean; rejectNullish: boolean; errorHandler: ErrorHandler | null; fixSmartQuotes: boolean; processLineBreaksAsNewText: boolean; maximumWalkingDepth?: number; }; type SandBox = { __code__: string | undefined; __result__: unknown | undefined; [k: string]: unknown; }; type Context = { gCntIf: number; gCntEndIf: number; level: number; fCmd: boolean; cmd: string; fSeekQuery: boolean; query?: string; buffers: { 'w:p': BufferStatus; 'w:tr': BufferStatus; 'w:tc': BufferStatus; }; pendingImageNode?: { image: NonTextNode; caption?: NonTextNode[]; }; imageAndShapeIdIncrement: number; images: Images; pendingLinkNode?: NonTextNode; linkId: number; links: Links; pendingHtmlNode?: TextNode | NonTextNode; htmlId: number; htmls: Htmls; vars: { [name: string]: VarValue; }; loops: Array; fJump: boolean; shorthands: { [shorthand: string]: string; }; options: CreateReportOptions; jsSandbox?: SandBox; textRunPropsNode?: NonTextNode; pIfCheckMap: Map; trIfCheckMap: Map; }; type Images = { [id: string]: Image; }; declare const ImageExtensions: readonly [".png", ".gif", ".jpg", ".jpeg", ".svg"]; type ImageExtension = (typeof ImageExtensions)[number]; type Image = { extension: ImageExtension; data: ArrayBuffer | string; }; type Links = { [id: string]: Link; }; type Link = { url: string; }; type Htmls = { [id: string]: string; }; type BufferStatus = { text: string; cmds: string; fInsertedText: boolean; }; type VarValue = unknown; type LoopStatus = { refNode: Node; refNodeLevel: number; varName: string; loopOver: Array; idx: number; isIf?: boolean; }; type CommandSummary = { raw: string; type: BuiltInCommand; code: string; }; type BuiltInCommand = (typeof BUILT_IN_COMMANDS)[number]; declare const BUILT_IN_COMMANDS: readonly ["QUERY", "CMD_NODE", "ALIAS", "FOR", "END-FOR", "IF", "END-IF", "INS", "EXEC", "IMAGE", "LINK", "HTML"]; /** * Create Report from docx template * * example: * ```js * const report = await 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; /** * 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; /** * 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; /** * 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 ['+++', '+++']) */ declare function listCommands(template: ArrayBuffer, delimiter?: string | [string, string]): Promise; /** * Extract metadata from a document, such as the number of pages or words. * @param template the docx template as a Buffer-like object */ declare function getMetadata(template: ArrayBuffer): Promise<{ pages: number | undefined; words: number | undefined; characters: number | undefined; lines: number | undefined; paragraphs: number | undefined; company: string | undefined; template: string | undefined; title: string | undefined; subject: string | undefined; creator: string | undefined; description: string | undefined; lastModifiedBy: string | undefined; revision: string | undefined; lastPrinted: string | undefined; created: string | undefined; modified: string | undefined; category: string | undefined; }>; declare function isError(err: unknown): err is Error; /** * Thrown when `rejectNullish` is set to `true` and a command returns `null` or `undefined`. */ declare class NullishCommandResultError extends Error { command: string; constructor(command: string); } /** * Thrown when the result of an `INS` command is an `Object`. This ensures you don't accidentally put `'[object Object]'` in your report. */ declare class ObjectCommandResultError extends Error { command: string; result: unknown; constructor(command: string, result: unknown); } declare class CommandSyntaxError extends Error { command: string; constructor(command: string); } declare class InvalidCommandError extends Error { command: string; constructor(msg: string, command: string); } declare class CommandExecutionError extends Error { command: string; err: Error; constructor(err: Error, command: string); } declare class ImageError extends CommandExecutionError { } declare class InternalError extends Error { constructor(msg: string); } declare class TemplateParseError extends Error { } declare class IncompleteConditionalStatementError extends Error { constructor(); } declare class UnterminatedForLoopError extends Error { constructor(loop: LoopStatus); } export { CommandExecutionError, CommandSyntaxError, ImageError, IncompleteConditionalStatementError, InternalError, InvalidCommandError, NullishCommandResultError, ObjectCommandResultError, QueryResolver, TemplateParseError, UnterminatedForLoopError, createReport, createReport as default, getMetadata, isError, listCommands };