🤖 Merge PR #50000 Update jsreport-core Configuration options by @newbish

* expanding jsreport-core type def

* add support for more configuration options

* recipe appears to be required

* engine can be 'none' but still needs to be defined

* template has to be partial to allow extensions

* fix tests

* changed [string] to string[]

* Update types/jsreport-core/index.d.ts

Co-authored-by: Ron Buckton <ron.buckton@microsoft.com>

* add name option

* document defaults

* attempt to provide type for defaults

Co-authored-by: Ron Buckton <ron.buckton@microsoft.com>
This commit is contained in:
Keith Kikta
2020-12-10 16:45:52 -06:00
committed by GitHub
parent eaa0740466
commit 875abec127
6 changed files with 224 additions and 41 deletions

View File

@@ -4,7 +4,7 @@ import JsRender = require("jsreport-jsrender");
import fs = require('fs');
const jsreport = JsReport({
tasks: {
templatingEngines: {
strategy: "http-server"
}
});

View File

@@ -2,11 +2,14 @@
// Project: http://jsreport.net
// Definitions by: taoqf <https://github.com/taoqf>
// pofider <https://github.com/pofider>
// Keith Kikta <https://github.com/newbish>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3
/// <reference types="node" />
import * as fs from 'fs';
declare namespace JsReport {
type Helpers = string | { [fun: string]: (...args: any[]) => any };
@@ -15,20 +18,45 @@ declare namespace JsReport {
type Recipe = "html";
interface Template {
/** template for the engine */
content: string;
/** templating engine used to assemble document */
engine: Engine | string;
helpers: Helpers;
/** javascript helper functions used by templating engines */
helpers?: Helpers;
/** recipe used for printing previously assembled document */
recipe: Recipe | string;
pathToEngine?: string;
name?: string;
}
interface Options {
interface RequestOptions {
preview?: boolean;
timeout?: number;
reportName?: string;
}
interface Request {
/** @default true */
value?: boolean;
/** @default false */
writable?: boolean;
/** @default false */
configurable?: boolean;
/** @default false */
enumerable?: boolean;
template: Partial<Template>;
options?: Options;
data: any;
options?: Partial<RequestOptions>;
context?: Context;
data?: any;
}
interface Context {
shared?: any;
originalInputDataIsEmpty?: boolean;
isChildRequest?: boolean;
logs: any;
timeoutLimit: number;
}
interface Response {
@@ -65,50 +93,198 @@ declare namespace JsReport {
directory: string;
}
interface Reporter {
use(extension: Extension | ExtensionDefinition): Reporter;
}
interface Reporter {
interface ReporterInstance {
defaults?: Defaults;
options?: Configuration;
afterRenderListeners: ListenerCollection;
afterTemplatingEnginesExecutedListeners: ListenerCollection;
beforeRenderListeners: ListenerCollection;
closeListeners: ListenerCollection;
documentStore: DocumentStore;
blobStorage: BlobStorage;
initializeListeners: ListenerCollection;
renderErrorListeners: ListenerCollection;
// it would be nice to add winston.LoggerInstance here
// however adding import winston = require('winston') breaks exported enums
logger: any;
logger?: any;
validateRenderListeners: ListenerCollection;
version: string;
version?: string;
settings: Settings;
optionsValidator: SchemaValidator;
entityTypeValidator: SchemaValidator;
}
interface Reporter extends ReporterInstance {
use(extension: Extension | ExtensionDefinition): Reporter;
init(): Promise<Reporter>;
render(options: Partial<Request>): Promise<Response>;
render(request: Request, parent?: Request): Promise<Response>;
discover(): Reporter;
createListenerCollection(): ListenerCollection;
close(): Promise<void>;
extensionsLoad(opts: any): Promise<Reporter>;
checkValidEntityName(c: string, doc: any, req: Request): Promise<void>;
createError(message: string, options?: any): any;
getAvailableRenderTimeout(req: Request, defaultValue: number): number;
executeScript(inputs: any, options: any, req: Request): Promise<any>;
afterConfigLoaded(cb: () => void): Reporter;
addRequestContextMetaConfig(property: any, options: any): void;
getRequestContextMetaConfig(property: any): any;
addPathToWatchForAutoCleanup(customPath: string): void;
getPathsToWatchForAutoCleanup(): string[];
ensureTempDirectoryExists(): Promise<TempDirectoryResult>;
readTempFile(filename: string, opts: any): Promise<ReadTempFileResult>;
writeTempFile(filenameFn: () => string, content: any, opts: any): Promise<WriteFileResult>;
readTempFileStream(filename: string, opts: any): Promise<ReadTempFileStreamResult>;
writeTempFileStream(filenameFn: () => string, opts: any): Promise<WriteFileStreamResult>;
silentLogs(logger: any): void;
}
interface Defaults {
loadConfig?: boolean;
rootDirectory?: string;
}
type ReporterOptionsStoreProvider = 'memory';
type ReporterOptionsBlobStorageProvider = 'memory' | 'fs';
type EngineStrategy = 'dedicated-process' | 'http-server' | 'in-process';
interface Configuration {
autoTempCleanup: boolean;
dataDirectory: string;
extensionsLocationCache: boolean;
loadConfig: boolean;
logger: {
silent: boolean;
mode?: any;
/** specifies where is the application root and where jsreport searches for extensions */
rootDirectory?: string;
/** specifies directory of the script that was used to start node.js, this value is mostly metadata that is useful for your own code inside jsreport scripts */
appDirectory?: string;
/**
* specifies where jsreport stores temporary files used by the conversion pipelineDef
* @default getDefaultTempDirectory()
*/
tempDirectory?: string;
/**
* specifies if jsreport should load configuration values from external sources (cli args, env vars, configuration files) or not
* @default getDefaultLoadConfig()
*/
loadConfig?: boolean;
/** specifies if after some interval jsreport should automatically clean up temporary files generated while rendering reports */
autoTempCleanup?: boolean;
/** specifies if jsreport should discover/search installed extensions in project and use them automatically */
discover?: boolean;
/**
* wheter if jsreport should read list of extensions from a previous generated cache or if it should crawl and try to search extensions again, set it to false when you want to always
* force crawling node_modules when searching for extensions while starting jsreport
* @default true
*/
useExtensionsLocationCache?: boolean;
logger?: {
silent?: boolean;
};
rootDirectory: string;
scripts: {
allowedModules: string[];
/** global single timeout that controls how much a report generation should wait before it times out */
reportTimeout?: number;
/**
* option that enables passing a custom report timeout per request using req.options.timeout. this enables that the caller of the report generation control the report timeout so enable it
* only when you trust the caller
* @default false
*/
enableRequestReportTimeout?: boolean;
/** @default false */
allowLocalFilesAccess?: boolean;
encryption?: {
/** lenght must be 16 characters */
secretKey: string;
/** @default true */
enabled?: boolean;
};
tasks: Partial<{
allowedModules: string[] | string;
strategy: "dedicated-process" | "http-server" | "in-process" | string;
}>;
tempDirectory: string;
templatingEngines?: {
/** @default 'dedicated-process' */
strategy?: EngineStrategy;
numberOfWorkers?: number;
forkOptions?: {
execArgv?: string | string[];
},
allowedModules?: string | string[];
timeout?: number;
templateCache?: {
max: number;
enabled: boolean;
}
};
store?: {
provider?: ReporterOptionsStoreProvider;
};
blobStorge?: {
provider?: ReporterOptionsBlobStorageProvider;
};
extensions?: any;
extensionsList?: string[];
/** @default true */
migrateEntitySetsToFolders?: boolean;
connectionString?: string;
}
interface Settings {
add(key: string, value: any, req: Request): any;
get(key: string): [SettingItem];
findValue(key: string, req: Request): any;
set(key: string, avalue: any, req: Request): any;
addOrSet(key: string, avalue: any, req: Request): number | null;
init(documentStore: any, authorization: any): any;
_collection: SettingItem[];
documentStore: any;
registerEntity(documentStore: any): void;
}
interface SettingItem {
key: string;
value: any;
}
interface SchemaValidator {
schemaVersion: string;
rootSchema: any;
getRootSchema(): any;
validateRoot(data: any, schema?: any): any;
addSchema(name: string, _schema: any, replace: boolean): void;
validate(name: string, data: any, schema?: any): any;
getSchema(name: string): any;
}
interface TempDirectoryResult {
directoryPath: string;
}
interface WriteFileResult {
pathToFile: string;
filename: string;
}
interface WriteFileStreamResult {
pathToFile: string;
filename: string;
stream: fs.WriteStream;
}
interface ReadTempFileResult {
pathToFile: string;
filename: string;
context: string;
}
interface ReadTempFileStreamResult {
pathToFile: string;
filename: string;
stream: fs.ReadStream;
}
interface BlobStorage {
registerProvider(provider: any): void;
read(...args: any): any;
write(...args: any): any;
remove(...args: any): Promise<any>;
init(): Promise<any>;
}
}
declare function JsReport(
config?: Partial<JsReport.Configuration>
config?: JsReport.Configuration,
defaults?: JsReport.Defaults,
): JsReport.Reporter;
export = JsReport;

View File

@@ -1,17 +1,24 @@
import JsReport = require('jsreport-core');
const template: JsReport.Template = {
content: '<h1>Hello {{:foo}}</h1>',
engine: 'jsrender',
recipe: 'phantom-pdf'
};
const options: JsReport.RequestOptions = { };
const request: JsReport.Request = {
template,
data: {
foo: "world"
},
options,
};
const jsreport = JsReport();
jsreport.init().then(() => {
return jsreport.render({
template: {
content: '<h1>Hello {{:foo}}</h1>',
engine: 'jsrender',
recipe: 'phantom-pdf'
},
data: {
foo: "world"
}
}).then((resp) => {
return jsreport.render(request).then((resp) => {
// prints pdf with headline Hello world
console.log(resp.content.toString());
});

View File

@@ -4,7 +4,7 @@ import JsRender = require("jsreport-jsrender");
import fs = require('fs');
const jsreport = JsReport({
tasks: {
templatingEngines: {
strategy: "http-server"
}
});

View File

@@ -4,7 +4,7 @@ import JsRender = require("jsreport-jsrender");
import fs = require('fs');
const jsreport = JsReport({
tasks: {
templatingEngines: {
strategy: "http-server"
}
});

View File

@@ -6,7 +6,7 @@
import { ExtensionDefinition } from 'jsreport-core';
declare module 'jsreport-core' {
interface Options {
interface RequestOptions {
reports?: JsReportReports.ReportsOptions;
}
}