/* eslint-disable */ import {IncomingHttpHeaders} from "http"; import { Buffer, Buffer as NonSharedBuffer } from "buffer"; /** * A hash array representing an Excel Row. * @desc Keys are the labels defined in the 1st row. */ export type ExcelRowHash = Record; /** * excel2JS conversion options. * @type {Object} * @property {string|number} [sheetName] Parse only this sheet, by name or index number. Defaults to every non-empty sheet * @property {boolean} [keepEmptyRows] Defaults to false * @property {number} [skipRowsBeforeHeader] Defaults to 0 * @property {number} [skipRowsAfterHeader] Defaults to 0 */ interface Excel2JsOptions { sheetName?: string | number; keepEmptyRows?: boolean; skipRowsBeforeHeader?: number; skipRowsAfterHeader?: number; } /** * The input of an Excel conversion can be a Buffer /decoded) or the path to a file */ export type Excel2JsInput = Buffer|string; /** * Read the content of a file and returns an object. * @desc object keys are sheet names, content is an array of rows, * @desc Each row is an array of hash arrays, whose keys are first row values (labels) * @function * @async * @param {Excel2JsInput} content The file content, a buffer object or the absolute path to a static file * @param {Excel2JsOptions} [options] Conversion options object * @param {string|number} [options.sheetName] Parse only this sheet, by name or index number. Defaults to every non-empty sheet * @param {boolean} [options.keepEmptyRows] Defaults to false * @param {number} [options.skipRowsBeforeHeader] Defaults to 0 * @param {number} [options.skipRowsAfterHeader] Defaults to 0 * @return { Promise> } */ export type Excel2JS = ( content: Excel2JsInput, options?: Excel2JsOptions ) => Promise>; /** * The simplified object of a mail. * @desc Mandatory properties: "to", "text" or "html" * @summary All recipients' properties can be a single recipient string, an array of strings or a comma-separated recipient's string. * @summary All the recipient strings can be simple email addresses or in the form "Name ". * @summary "from" isn't allowed, it's set by server's configuration (in any case config can be passed different on each message) * @type {Object} * @property {string|string[]} to Array or comma-separated list of recipients * @property {string|string[]} [cc] Array or comma-separated list of recipients * @property {string|string[]} [bcc] Array or comma-separated list of recipients * @property {Record} [headers] Additional headers, if any * @property {'high'|'normal'|'low'} [priority] Defaults to "normal" * @property {string} subject Email subject * @property {string} [text] Text version of the mail * @property {string} [html] HTML version of the mail */ export interface DrsMailMessageObject { to : string|string[]; cc?: string|string[]; bcc?: string|string[]; headers?: Record; priority?: 'high'|'normal'|'low'; subject?: string; text?: string; html?: string; } /** * Mailer configuration * @type {Object} * @property {string} host SMTP address (IP or iname) * @property {number} port SMTP port * @property {string} from Sender,as email address or "name
" * @property {boolean} [secure] Start the connection secure (defaults to false, can start TLS later) * @property {string} [authType] Defaults to "login" * @property {string} [authUser] User ID for SMTP authentication * @property {string} [authPassword] Password for SMTP authentication */ export interface DrsMailMessageConfig { host: string; port: number; from: string; secure?: boolean; authType?: string; authUser?: string; authPassword?: string; } /** * The param object to send an email * @type {Object} * @property {DrsMailMessageObject} message The message * @property {DrsMailMessageConfig} [mailConfig] Optional mail configuration */ export interface DrsMailMessageParams { message: DrsMailMessageObject; mailConfig?: DrsMailMessageConfig; } export interface DrsHelperNewItemCoordinates { id?: string; entity?: string; schema?: string; } export interface DrsHelperItemCoordinates { id:string; entity?: string; schema?: string; } /** * Import a script (js or mjs) or fetch a file (JSON or text) external to the operation .mjs file * @abstract This method can be used to read various file types: * * .json files: are converted into a data object * * .js/.mjs files: are imported, acting exactly like drs.import() * * any other file type: its content is returned in a string, parsed UTF-8. * @function * @async * @param {string} path * @return {Promise} */ export type DrsHelperFunctionFetchConfig = (path:string) => Promise; /** * List a dataset, a schema or an entity * * In case of dataset or schema directory names are returned without the trailing "/" * * The list is aware of transaction changes not committed yet * @function * @param {string} [schema] * @param {string} [entity] * @return {string[]} */ export type DrsHelperFunctionList = (schema?:string, entity?:string ) => string[]; /** * Returns true if memory cell exists and isn't empty, false otherwise. * @function * @param {DrsHelperItemCoordinates|string} coords coordinates or ID * @return {boolean} Memory cell file exists and has at least one key */ export type DrsHelperFunctionExists = (coords: DrsHelperItemCoordinates|string ) => boolean; /** * Read a JSON file from data, returns undefined if file doesn't exist. * @function * @param {DrsHelperItemCoordinates|string} coords coordinates or ID * @return {object|undefined} File content parsed, undefined if file doesn't exist */ export type DrsHelperFunctionGet = (coords: DrsHelperItemCoordinates|string ) => object|undefined; /** * Set a JSON file in data, deletes it if content is undefined * @function * @param {DrsHelperNewItemCoordinates|string} [coords] coordinates or ID, defaults to current values and auto-generated ID * @param {object|string} [content] An Object, or its JSON, or undefined to delete the file * @return {string} The ID */ export type DrsHelperFunctionSet = (coords: DrsHelperNewItemCoordinates|string|undefined, content?: object|string ) => string; /** * Delete a JSON file in data * @function * @param {DrsHelperNewItemCoordinates|string} coords coordinates or ID, defaults to current values and auto-generated ID * @return {string} The ID */ export type DrsHelperFunctionRm = (coords: DrsHelperNewItemCoordinates|string ) => string; /** * Execute a MariaDB statement (with or without bind values) and returns result (if any). * @param {string} sql The SQL statement to be executed * @param {Array} [values] Values to bind, if any * @return {Promise} */ export type DrsHelperFunctionSql = (sql: string, values?:Array ) => Promise; /** * Execute a INSERT/ON DUPLICATE KEY UPDATE returning inserted rows * @param {string} table Table name * @param {Record|Record[]} data The * @return {Promise[]>} */ export type DrsHelperFunctionInsert = (table: string, data: Record|Record[] ) => Promise[]>; /** * Check if table exists, otherwise optionally create it * @param {string} tableName * @param {string} [creationSql] * @return {Promise} */ export type DrsHelperFunctionCheckSqlTable = (tableName: string, creationSql?:string ) => Promise; /** * Send an email * @function * @param {DrsMailMessageParams|DrsMailMessageObject} params * @return {Promise} */ export type DrsHelperFunctionMail = (params: DrsMailMessageParams|DrsMailMessageObject ) => Promise; /** * List the content of a dir under (a) dump location * * Returns false if not allowed or not recognized * * Throws a 403 if trying to lost out of allowed scope(s) defined by dumpRoot location(s) * * Returns a list of file names and directory names (with trailing "/"). * * The list is aware of transaction changes not committed yet * @function * @param {string} [path] In the form "dumpKey:relative/path", "dumpKey:", "relativePath" or "" * @return {string[]|false} */ export type DrsHelperFunctionDumpList = (path?: string ) => string[]|false; /** * Get the content of a static file under (some) dumpRoot * * Returns undefined if file doesn't exist * * Throws a 403 if trying to lost out of allowed scope(s) defined by dumpRoot location(s) * * Returns UTF-8 content of file otherwise. * @function * @param {string} path In the form "dumpKey:relative/path/to/file" or "relative/path/to/file" * @return {string|undefined} */ export type DrsHelperFunctionDumpGet = (path: string ) => string|undefined; /** * Set the content of a static file under (some) dumpRoot, deletes it if content is undefined * * Throws a 403 if trying to lost out of allowed scope(s) defined by dumpRoot location(s) * * Returns file name * @function * @param {string} path In the form "dumpKey:relative/path/to/file" or "relative/path/to/file" * @param {any} [content] * @return {string|undefined} */ export type DrsHelperFunctionDumpSet = (path: string, content?:any ) => string|undefined; /** * Commit changes to DB and file-system * @function * @return {void} */ export type DrsHelperFunctionCommit = () => void; /** * Revert non-committed changed to DB and file-system * @function * @return {void} */ export type DrsHelperFunctionRollback = () => void; /** * Send (once) the output for request, while further send action(s) will be ignored * @abstract Send is automatically performe with the returned result of the operation. * @abstract On the other hand, especially in case of time-consuming async processes, or in case of processes * requiring a callback, it's possible to send quickly a response and then keep the operation running. * @abstract Note: sending an error doesn't stop the script, nor perform rollback. * If you want to stop the script and perform a drs.rollback() throw instead an Error(). * @function * @param {object|string|Error} what The content to be sent * @param {string} [ContentType] The optional content-type (ignored for a javascript object) * @return {void} * @see {DrsHelperFunctionRollback} * @example * drs.send( { foo: "bar" }); * drs.send( "Hello world!"); * drs.send( new Error("Scrambled data") ); */ export type DrsHelperFunctionSend = ( what: object|string|Error, ContentType?:string ) => void; /** * The params for a sub-operation * @type {Record} * @property {string} [schema] The schema name, overwritten if derived from URI * @property {string} [entity] The entity name, overwritten if derived from URI * @property {string} operation The operation, overwritten if derived from URI * @property {boolean|number|"true"|"false"|"Yes"|"Y"|"No"|"N"} [dry_run] Set to true or deleted after backend analysis. * If true, all changes to files and DB aren't committed. */ export interface DrsDbOperationSubObjectParams { schema?: string; entity?: string; operation: string; dry_run?: boolean|number|"true"|"false"|"Yes"|"Y"|"No"|"N"; } /** * Can be an object or operation name. * @see {DrsDbOperationSubObjectParams} */ export type DrsDbOperationSubParams = DrsDbOperationSubObjectParams|string; /** * A subprocess internal call * @param {DrsDbOperationSubParams} params * @param {any} data * @return {Promise} * @see {DrsDbOperationSubObjectParams} */ export type DrsHelperFunctionSub = ( params: DrsDbOperationSubParams, data?: any ) => Promise; /** * A subprocess detached call * @param {DrsDbOperationSubParams} params * @param {any} data * @return {void} * @see {DrsDbOperationSubObjectParams} */ export type DrsHelperFunctionDetach = ( params: DrsDbOperationSubParams, data?: any ) => void; /** * Fetch a resource using node-fetch * @function * @param {string} URL * @param {RequestInit} [RequestInit] * @return {Promise} */ export type DrsHelperFunctionFetch = ( URL: string, RequestInit?: RequestInit ) => Promise; /** * Import an external javascript using node-fetch * @function * @param {string} URL * @param {RequestInit} [RequestInit] * @return {Promise} */ export type DrsHelperFunctionImport = ( URL: string, RequestInit?: RequestInit ) => Promise; /** * Debug: console some values * @function * @params {any[]} * @return {void} */ export type DrsHelperFunctionConsole = ( any: any ) => void; /** * Debug: Send log to dataset's log.txt * @function * @param {string|Error|number|Object} what The content to be sent * @return {void} */ export type DrsHelperFunctionLog = ( what: string|Error|number|Object ) => void; /** * Import an extension module * @function * @param {string} extName * @return {Promise} */ export type DrsHelperFunctionExtension = ( extName?: string ) => Promise; /** * Helper to manage ZIP archives to be sent in response * @type {Object} * @property {(coords: DrsHelperItemCoordinates|string): Promise} add Add item(s) or a whole entity to the Zip archive, returns archive size * @property {()=>void} dispose Remove temporary files, automatically managed by DrsHelperObject * @property { ( fileName?: string )=> NonSharedBuffer } send Sets response headers and return buffer for operation "return": return myZip.send() */ export interface zipHelperObject { add(coords: DrsHelperItemCoordinates|string): Promise; send( fileName?: string ): NonSharedBuffer; dispose(): void; } export interface DrsHelperFunctionReturn { stdout: string, stderr: string, errorcode?: number, error?: Error } /** * Exec a shell command * @function * @async * @param {string} command * @param {Record|string} options options object or Current Work Directory * @return {Promise} */ export type DrsHelperFunctionExec = ( command: string, options: Record|string ) => Promise; /** * @desc A shelf where we can put and retrieve stuff * @abstract Notes about the shelf: * * The shelf lives as soon as the drs object, initially empty * * Can hosld objects of whatever nature, because object themselves are returned - not a clone * * Implication: in case of objects (arrays, etc.) changes propagate to the original item stored in the shelf * @function * @param {string} [key] The name of the item on the shelf. If missing a list of object names is returned. * @param {null|any} [value] The value of the object. null deletes the object, if missing the actual value is returned * @return {string[]|undefined|any} * @usage There are 4 ways to use it: * * drs.shelf() => list of stored objects name * * drs.shelf('name') => the stored vale of 'name' item - or undefined * * drs.shelf('name', null) => undefined, removes object 'name' from the shelf * * drs.shelf('name', anyvalue) => anyvalue, put object 'name' on the shelf, replacing it if already there */ export type DrsHelperFunctionShelf = ( key?: string, value?: null|any ) => string[]|undefined|any; /** * The DRS helper object sent to operation scripts. * @abstract This object provides interaction with the backend of DRS. * @abstract At the same time it strictly limits the action to the current dataset: * * SQL access is restricted to the only defined db, if any * * Memory cell files can be read/write only under the dataset's umbrella (defined dataRoot) * * Config scripts/files can be retrieved only under the dataset's configRoot * * Static files are restricted to defined dumpRoot location(s), if any. * @type {Object} * @property {DrsHelperFunctionFetchConfig} config Import a script (js or mjs) or fetch a file (JSON or text) external to the operation .mjs file * @property { (string)=>string } atob Base64 decode * @property { (string)=>string } btoa Base64 encode * @property { (src: any)=> any } clone Clone a structured object * @property { (clearText: string) => Promise Promise } cryptVerify Verify match with encrypted value * @property {DrsHelperFunctionList} list List a dataset, a schema or an entity * @property {()=>string} generateUid Generate a UUID * @property {DrsHelperFunctionShelf} shelf Manage DRS object's shelf * @property {DrsHelperFunctionExists} exists True if memory cell file exists and has at least one key * @property {DrsHelperFunctionGet} get Read a JSON file from data, returns undefined if file doesn't exist. * @property {DrsHelperFunctionSet} set Set a JSON file in data, deletes it if content is undefined * @property {DrsHelperFunctionRm} rm Delete a JSON file in data * @property {DrsHelperFunctionSql} sql Execute a MariaDB statement (with or without bind values) and returns result (if any). * @property {DrsHelperFunctionInsert} insert Execute a INSERT/ON DUPLICATE KEY UPDATE returning inserted rows * @property {DrsHelperFunctionCheckSqlTable} checkSqlTable Check if table exists, otherwise optionally create it * @property {DrsHelperFunctionMail} mail Send an email * @property {DrsHelperFunctionDumpSet} dump Set the content of a static file under (some) dumpRoot, deletes it if content is undefined * @property {DrsHelperFunctionDumpList} dumpList List the content of a dir under (a) dump location * @property {DrsHelperFunctionDumpGet} dumpGet Get the content of a static file under (some) dumpRoot * @property {DrsHelperFunctionCommit} commit Commit changes to DB and file-system * @property {DrsHelperFunctionRollback} rollback Revert non-committed changed to DB and file-system * @property {DrsHelperFunctionSend} send Send (once) the output for request, while further send action(s) will be ignored * @property {DrsHelperFunctionSub} sub A subprocess internal call * @property {DrsHelperFunctionShelf} detach A detached subprocess call * @property {DrsHelperFunctionFetch} fetch Fetch a resource using node-fetch * @property {DrsHelperFunctionImport} import Import an external javascript * @property {DrsHelperFunctionConsole} console Debug: console some values * @property {DrsHelperFunctionLog} log Debug: Send log to dataset's log.txt * @property {zipHelperObject} zipOut Returns a new zipHelperObject for response * @property {DrsHelperFunctionExtension} extension Import an extension module */ export interface DrsHelperObject { config: DrsHelperFunctionFetchConfig; atob(string):string; btoa(string):string; clone( src: any) : any; encrypt( clearText: string ): Promise; cryptVerify(encrypted:string,clearText:string,options?:{secret?: Buffer}): Promise; list : DrsHelperFunctionList; exists: DrsHelperFunctionExists; get : DrsHelperFunctionGet; generateUid(): string; shelf: DrsHelperFunctionShelf; set : DrsHelperFunctionSet; rm : DrsHelperFunctionRm; sql: DrsHelperFunctionSql; insert: DrsHelperFunctionInsert; checkSqlTable: DrsHelperFunctionCheckSqlTable; mail: DrsHelperFunctionMail; dump: DrsHelperFunctionDumpSet; dumpList: DrsHelperFunctionDumpList; dumpGet: DrsHelperFunctionDumpGet; commit: DrsHelperFunctionCommit; rollback: DrsHelperFunctionRollback; send: DrsHelperFunctionSend; sub: DrsHelperFunctionSub; detach: DrsHelperFunctionShelf; fetch: DrsHelperFunctionFetch; import: DrsHelperFunctionImport; console: DrsHelperFunctionConsole, log: DrsHelperFunctionLog, exec: DrsHelperFunctionExec, zipOut: zipHelperObject; extension: DrsHelperFunctionExtension; } export interface DrsOperationEnv extends Record { dataset: Record; headers: IncomingHttpHeaders; } /** * The params the operation script will receive. * @abstract The params are sent with request, but besides those input params: * * these keys are set by the backend, * * or are deleted if necessary * @type {Record} * @property {string} dataset The dataset name, overwritten if derived from URI * @property {string} schema The schema name, overwritten if derived from URI * @property {string} entity The entity name, overwritten if derived from URI * @property {string} operation The operation, overwritten if derived from URI * @property {boolean|number|"true"|"false"|"Yes"|"Y"|"No"|"N"} [dry_run] Set to true or deleted after backend analysis. * If true, all changes to files and DB aren't committed. * @property {string|false} [auth_type] Written/deleted by backend depending on dataset configuration. * False means that no authentication is requested. * @property {string} [auth_user] Written/deleted by backend, reports user authenticated if any. * @property {Record} [auth_flags] Written/deleted by backend, reports optional flags associated to an authenticated user. * @property {"xml"|"json} [output] Output format */ export interface DrsDbOperationParams extends Record { dataset: string; schema: string; entity: string; operation: string; dry_run?: boolean|number|"true"|"false"|"Yes"|"Y"|"No"|"N"; auth_type?: string|string[]|false; auth_user?: string; auth_flags?: Record; output?: "xml"|"json"; } export interface DrsDbOperationEnv extends Record { dataset: Record; headers: IncomingHttpHeaders; } export interface DrsDbOperationIncomingContext { params: DrsDbOperationParams; env: DrsDbOperationEnv; data: Record; } export type DrsOperation = (ctx: DrsDbOperationIncomingContext, drs: DrsHelperObject ) => Promise; export type ExcelCellValue = (string | number | boolean | Date); export type ExcelRow = ExcelCellValue[]; export type ExcelSheet = ExcelRow[];