Skip to content

Commit

Permalink
Added missing envs, validation middleware, validation enhancements, o…
Browse files Browse the repository at this point in the history
…verall options, scenarios and test corrections.
  • Loading branch information
PaulDalek committed Oct 9, 2024
1 parent f6cef24 commit 4739643
Show file tree
Hide file tree
Showing 28 changed files with 1,767 additions and 1,083 deletions.
18 changes: 18 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,34 @@ HIGHCHARTS_INDICATOR_SCRIPTS =
HIGHCHARTS_CUSTOM_SCRIPTS =

# EXPORT CONFIG
EXPORT_INFILE =
EXPORT_INSTR =
EXPORT_OPTIONS =
EXPORT_SVG =
EXPORT_TYPE = png
EXPORT_CONSTR = chart
EXPORT_OUTFILE =
EXPORT_B64 = false
EXPORT_NO_DOWNLOAD = false
EXPORT_HEIGHT =
EXPORT_WIDTH =
EXPORT_SCALE =
EXPORT_DEFAULT_HEIGHT = 400
EXPORT_DEFAULT_WIDTH = 600
EXPORT_DEFAULT_SCALE = 1
EXPORT_GLOBAL_OPTIONS =
EXPORT_THEME_OPTIONS =
EXPORT_BATCH =
EXPORT_RASTERIZATION_TIMEOUT = 1500

# CUSTOM LOGIC CONFIG
CUSTOM_LOGIC_ALLOW_CODE_EXECUTION = false
CUSTOM_LOGIC_ALLOW_FILE_RESOURCES = false
CUSTOM_LOGIC_CUSTOM_CODE =
CUSTOM_LOGIC_CALLBACK =
CUSTOM_LOGIC_RESOURCES =
CUSTOM_LOGIC_LOAD_CONFIG =
CUSTOM_LOGIC_CREATE_CONFIG =

# SERVER CONFIG
SERVER_ENABLE = false
Expand Down
142 changes: 85 additions & 57 deletions README.md

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,13 @@ async function start() {
const args = process.argv;

// Display version information if requested
if (
['-v', '--v', '-version', '--version'].includes(args[args.length - 1])
) {
if (['-v', '--v'].includes(args[args.length - 1])) {
// Print logo with the version information
return printVersion();
}

// Display help information if requested
if (['-h', '--h', '-help', '--help'].includes(args[args.length - 1])) {
if (['-h', '--h'].includes(args[args.length - 1])) {
// Print logo with the version information
return printUsage();
}
Expand Down
2 changes: 2 additions & 0 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export async function createBrowser(puppeteerArgs = []) {
headless: other.browserShellMode ? 'shell' : true,
userDataDir: 'tmp',
args: puppeteerArgs,
// Must be disabled for debugging to work
pipe: !enabledDebug,
handleSIGINT: false,
handleSIGTERM: false,
handleSIGHUP: false,
Expand Down
20 changes: 16 additions & 4 deletions lib/chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
roundNumber,
wrapAround
} from './utils.js';
import { validateOption } from './validate.js';
import { strictValidate, validateOption } from './validate.js';

import ExportError from './errors/ExportError.js';

Expand Down Expand Up @@ -53,13 +53,13 @@ export async function startExport(options = getOptions(), endCallback) {
const exportOptions = options.export;

// Export using SVG as an input
if (options.payload.svg !== null) {
if (exportOptions.svg !== null) {
try {
log(4, '[chart] Attempting to export from an SVG input.');

// Export from an SVG string
const result = _exportAsString(
sanitize(options.payload.svg), // #209
sanitize(exportOptions.svg), // #209
options,
endCallback
);
Expand Down Expand Up @@ -308,7 +308,10 @@ function _doStraightInject(options, endCallback) {
} catch (error) {
return endCallback(
new ExportError(
`[chart] Malformed input detected for ${options.export?.requestId || '?'}. Please make sure that your JSON/JavaScript options are sent using the "options" attribute, and that if you're using SVG, it is unescaped.`
(options.export?.requestId
? `[chart] Malformed input detected for the request: ${options.export?.requestId}. `
: '[chart] Malformed input detected. ') +
'Please make sure that your JSON/JavaScript options are sent using the "options" attribute, and that if you are using SVG, it is unescaped.'
).setError(error)
);
}
Expand Down Expand Up @@ -414,6 +417,15 @@ async function _prepareExport(options, endCallback, json, svg) {
..._findChartSize(exportOptions)
};

/// TO DO: Check if it is needed, the height error occurs here
// The last strict validation of options right before exporting process
// try {
// // Validate final options
// options = strictValidate(options);
// } catch (error) {
// logZodIssues(1, error.issues, '[config] Final options validation error');
// }

// Post the work to the pool
try {
const result = await postWork(exportOptions.strInj || json || svg, options);
Expand Down
5 changes: 0 additions & 5 deletions lib/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,6 @@ export function enableFileLogging(dest, file) {
file,
toFile: true
};

// Need a correct logs destination
if (logging.dest.length === 0) {
return log(1, '[logger] File logging initialization: no path supplied.');
}
}

/**
Expand Down
157 changes: 102 additions & 55 deletions lib/schemas/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export const defaultConfig = {
],
type: ['string[]'],
envLink: 'PUPPETEER_ARGS',
cliName: 'puppeteerArgs',
description: 'Array of Puppeteer arguments',
promptOptions: {
type: 'list',
Expand Down Expand Up @@ -226,6 +227,7 @@ export const defaultConfig = {
'https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data.min.js'
],
type: ['string[]'],
envLink: 'HIGHCHARTS_CUSTOM_SCRIPTS',
description: 'Additional custom scripts or dependencies to fetch',
promptOptions: {
type: 'list',
Expand All @@ -237,23 +239,45 @@ export const defaultConfig = {
infile: {
value: null,
type: ['string', 'null'],
envLink: 'EXPORT_INFILE',
description:
'Input filename with type, formatted correctly as JSON or SVG'
'Input filename with type, formatted correctly as JSON or SVG',
promptOptions: {
type: 'text'
}
},
instr: {
value: null,
type: ['object', 'string', 'null'],
envLink: 'EXPORT_INSTR',
description:
'Overrides the `infile` with JSON, stringified JSON, or SVG input'
'Overrides the `infile` with JSON, stringified JSON, or SVG input',
promptOptions: {
type: 'text'
}
},
options: {
value: null,
type: ['object', 'string', 'null'],
description: 'Alias for the `instr` option'
envLink: 'EXPORT_OPTIONS',
description: 'Alias for the `instr` option',
promptOptions: {
type: 'text'
}
},
svg: {
value: null,
type: ['string', 'null'],
envLink: 'EXPORT_SVG',
description: 'SVG string representation of the chart to render',
promptOptions: {
type: 'text'
}
},
outfile: {
value: null,
type: ['string', 'null'],
envLink: 'EXPORT_OUTFILE',
description:
'Output filename with type. Can be jpeg, png, pdf, or svg and ignores `type` option',
promptOptions: {
Expand Down Expand Up @@ -283,6 +307,26 @@ export const defaultConfig = {
choices: ['chart', 'stockChart', 'mapChart', 'ganttChart']
}
},
b64: {
value: false,
type: ['boolean'],
envLink: 'EXPORT_B64',
description:
'Whether or not to the chart should be received in base64 format instead of binary',
promptOptions: {
type: 'toggle'
}
},
noDownload: {
value: false,
type: ['boolean'],
envLink: 'EXPORT_NO_DOWNLOAD',
description:
'Whether or not to include or exclude attachment headers in the response',
promptOptions: {
type: 'toggle'
}
},
defaultHeight: {
value: 400,
type: ['number'],
Expand Down Expand Up @@ -316,36 +360,60 @@ export const defaultConfig = {
height: {
value: null,
type: ['number', 'null'],
description: 'Height of the exported chart, overrides chart settings'
envLink: 'EXPORT_HEIGHT',
description: 'Height of the exported chart, overrides chart settings',
promptOptions: {
type: 'number'
}
},
width: {
value: null,
type: ['number', 'null'],
description: 'Width of the exported chart, overrides chart settings'
envLink: 'EXPORT_WIDTH',
description: 'Width of the exported chart, overrides chart settings',
promptOptions: {
type: 'number'
}
},
scale: {
value: null,
type: ['number', 'null'],
envLink: 'EXPORT_SCALE',
description:
'Scale of the exported chart, overrides chart settings. Ranges from 0.1 to 5.0'
'Scale of the exported chart, overrides chart settings. Ranges from 0.1 to 5.0',
promptOptions: {
type: 'number'
}
},
globalOptions: {
value: null,
type: ['object', 'string', 'null'],
envLink: 'EXPORT_GLOBAL_OPTIONS',
description:
'JSON, stringified JSON or filename with global options for Highcharts.setOptions'
'JSON, stringified JSON or filename with global options for Highcharts.setOptions',
promptOptions: {
type: 'text'
}
},
themeOptions: {
value: null,
type: ['object', 'string', 'null'],
envLink: 'EXPORT_THEME_OPTIONS',
description:
'JSON, stringified JSON or filename with theme options for Highcharts.setOptions'
'JSON, stringified JSON or filename with theme options for Highcharts.setOptions',
promptOptions: {
type: 'text'
}
},
batch: {
value: null,
type: ['string', 'null'],
envLink: 'EXPORT_BATCH',
description:
'Batch job string with input/output pairs: "in=out;in=out;..."'
'Batch job string with input/output pairs: "in=out;in=out;..."',
promptOptions: {
type: 'text'
}
},
rasterizationTimeout: {
value: 1500,
Expand Down Expand Up @@ -381,32 +449,52 @@ export const defaultConfig = {
customCode: {
value: null,
type: ['string', 'null'],
envLink: 'CUSTOM_LOGIC_CUSTOM_CODE',
description:
'Custom code to execute before chart initialization. Can be a function, code wrapped in a function, or a .js filename'
'Custom code to execute before chart initialization. Can be a function, code wrapped in a function, or a .js filename',
promptOptions: {
type: 'text'
}
},
callback: {
value: null,
type: ['string', 'null'],
envLink: 'CUSTOM_LOGIC_CALLBACK',
description:
'JavaScript code to run during construction. Can be a function or a .js filename'
'JavaScript code to run during construction. Can be a function or a .js filename',
promptOptions: {
type: 'text'
}
},
resources: {
value: null,
type: ['object', 'string', 'null'],
envLink: 'CUSTOM_LOGIC_RESOURCES',
description:
'Additional resources as JSON, stringified JSON, or filename, containing files, js, and css sections'
'Additional resources as JSON, stringified JSON, or filename, containing files, js, and css sections',
promptOptions: {
type: 'text'
}
},
loadConfig: {
value: null,
type: ['string', 'null'],
envLink: 'CUSTOM_LOGIC_LOAD_CONFIG',
legacyName: 'fromFile',
description: 'File with a pre-defined configuration to use'
description: 'File with a pre-defined configuration to use',
promptOptions: {
type: 'text'
}
},
createConfig: {
value: null,
type: ['string', 'null'],
envLink: 'CUSTOM_LOGIC_CREATE_CONFIG',
description:
'Prompt-based option setting, saved to a provided config file'
'Prompt-based option setting, saved to a provided config file',
promptOptions: {
type: 'text'
}
}
},
server: {
Expand Down Expand Up @@ -980,47 +1068,6 @@ export const defaultConfig = {
promptOptions: {
type: 'text'
}
},
secret: {
value: null,
type: ['string', 'null'],
envLink: 'WEB_SOCKET_SECRET',
cliName: 'wsSecret',
description:
'Secret used to create a JSON Web Token for the WebSocket server',
promptOptions: {
type: 'text'
}
}
},
payload: {
svg: {
value: null,
type: ['string', 'null'],
description: 'SVG string representation of the chart to render'
},
b64: {
value: false,
type: ['boolean'],
description:
'Whether or not to the chart should be received in base64 format instead of binary',
promptOptions: {
type: 'toggle'
}
},
noDownload: {
value: false,
type: ['boolean'],
description:
'Whether or not to include or exclude attachment headers in the response',
promptOptions: {
type: 'toggle'
}
},
requestId: {
value: null,
type: ['string', 'null'],
description: 'Unique identifier for each request served by the server'
}
}
};
Expand Down
Loading

0 comments on commit 4739643

Please sign in to comment.