From 321dbbb5d7e7eb3b7ef24d1c99eb7810906a2453 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Fri, 30 Dec 2022 21:35:06 +0530 Subject: [PATCH 1/8] feat: allow mermaid to be configured via some query params --- mermaid/src/index.js | 5 +++-- mermaid/src/worker.js | 12 +++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/mermaid/src/index.js b/mermaid/src/index.js index bde457e59..da8912a57 100644 --- a/mermaid/src/index.js +++ b/mermaid/src/index.js @@ -12,13 +12,14 @@ const instance = require('./browser-instance') const server = micro(async (req, res) => { // TODO: add a /_status route (return mermaid version) // TODO: read the diagram source as plain text - const outputType = req.url.match(/\/(png|svg)$/)?.[1] + const url = new URL(req.url, 'http://localhost') // create a URL object. The base is not important here + const outputType = url.pathname.match(/\/(png|svg)$/)?.[1] if (outputType) { const diagramSource = await micro.text(req, { limit: '1mb', encoding: 'utf8' }) if (diagramSource) { try { const isPng = outputType === 'png' - const output = await worker.convert(new Task(diagramSource, isPng)) + const output = await worker.convert(new Task(diagramSource, isPng), url.searchParams) res.setHeader('Content-Type', isPng ? 'image/png' : 'image/svg+xml') return micro.send(res, 200, output) } catch (err) { diff --git a/mermaid/src/worker.js b/mermaid/src/worker.js index 998602003..5310aeb67 100644 --- a/mermaid/src/worker.js +++ b/mermaid/src/worker.js @@ -15,12 +15,13 @@ class Worker { this.pageUrl = process.env.KROKI_MERMAID_PAGE_URL || `file://${path.join(__dirname, '..', 'assets', 'index.html')}` } - async convert (task) { + async convert (task, config) { const browser = await puppeteer.connect({ browserWSEndpoint: this.browserWSEndpoint, ignoreHTTPSErrors: true }) const page = await browser.newPage() + this.updateConfig(task, config) try { page.setViewport({ height: 800, width: 600 }) await page.goto(this.pageUrl) @@ -65,6 +66,15 @@ class Worker { } } } + + updateConfig (task, config) { + for (const property in task.mermaidConfig) { + // for now only properties with string values are handled + if(typeof task.mermaidConfig[property] === 'string') { + task.mermaidConfig[property] = config.get(property) + } + } + } } module.exports = { From 9f7e53ea68704b4db26108cb99b5bd369d16c867 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Sat, 31 Dec 2022 16:27:29 +0530 Subject: [PATCH 2/8] fix: undefined when no params are passed --- mermaid/src/worker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mermaid/src/worker.js b/mermaid/src/worker.js index 5310aeb67..c2fbf2ce5 100644 --- a/mermaid/src/worker.js +++ b/mermaid/src/worker.js @@ -70,7 +70,7 @@ class Worker { updateConfig (task, config) { for (const property in task.mermaidConfig) { // for now only properties with string values are handled - if(typeof task.mermaidConfig[property] === 'string') { + if(typeof task.mermaidConfig[property] === 'string' && config.get(property)) { task.mermaidConfig[property] = config.get(property) } } From ac760148e99fcb0159a8c5bc68b8d7ed8e2411a1 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Mon, 2 Jan 2023 15:28:32 +0530 Subject: [PATCH 3/8] feat: allow other types of parameter --- mermaid/package-lock.json | 1 + mermaid/package.json | 3 ++- mermaid/src/worker.js | 22 +++++++++++++++++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/mermaid/package-lock.json b/mermaid/package-lock.json index bb85f1ab5..22fb3114b 100644 --- a/mermaid/package-lock.json +++ b/mermaid/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "lodash": "^4.17.21", "micro": "9.4.1", "pino": "8.8.0", "pino-debug": "2.0.0", diff --git a/mermaid/package.json b/mermaid/package.json index f0fde878c..5d005c3b3 100644 --- a/mermaid/package.json +++ b/mermaid/package.json @@ -18,15 +18,16 @@ "url": "https://github.com/yuzutech/kroki.git" }, "dependencies": { + "lodash": "^4.17.21", "micro": "9.4.1", "pino": "8.8.0", "pino-debug": "2.0.0", "puppeteer": "14.4.1" }, "devDependencies": { - "mermaid": "9.3.0", "chai": "4.3.7", "dirty-chai": "^2.0.1", + "mermaid": "9.3.0", "mocha": "10.2.0", "pngjs": "^6.0.0", "standard": "17.0.0" diff --git a/mermaid/src/worker.js b/mermaid/src/worker.js index c2fbf2ce5..d58700a82 100644 --- a/mermaid/src/worker.js +++ b/mermaid/src/worker.js @@ -2,6 +2,7 @@ const { logger } = require('./logger') const path = require('path') const puppeteer = require('puppeteer') +const _ = require('lodash') class SyntaxError extends Error { constructor () { @@ -68,12 +69,23 @@ class Worker { } updateConfig (task, config) { - for (const property in task.mermaidConfig) { - // for now only properties with string values are handled - if(typeof task.mermaidConfig[property] === 'string' && config.get(property)) { - task.mermaidConfig[property] = config.get(property) - } + for (const property in Object.fromEntries(config)) { + let value = this.getTypedValue(config.get(property)) + _.set(task.mermaidConfig, property, value) + } + } + + getTypedValue(value){ + if(value.toLowerCase() === 'true' || value.toLocaleString() === 'false'){ + return value === 'true' + } + if(value.startsWith('[') && value.endsWith(']')) { + return value.substring(1,value.length - 1).split(',').map(item=>this.getTypedValue(item)) + } + if(!isNaN(value)){ + return Number(value) } + return value } } From 7b3b76be9110de697f86163b05fa3f5c79069ce0 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Mon, 2 Jan 2023 21:43:38 +0530 Subject: [PATCH 4/8] feat: handle configuration options in the form of `kroki-diagram-options-er_use-max-width` where the mermaid option is `er.useMaxWidth` --- mermaid/src/worker.js | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/mermaid/src/worker.js b/mermaid/src/worker.js index d58700a82..1397349a3 100644 --- a/mermaid/src/worker.js +++ b/mermaid/src/worker.js @@ -70,19 +70,38 @@ class Worker { updateConfig (task, config) { for (const property in Object.fromEntries(config)) { - let value = this.getTypedValue(config.get(property)) - _.set(task.mermaidConfig, property, value) + const propertyCamelCase = this.convertPropertyToCamelCase(property) + let value = this.getTypedValue(config.get(propertyCamelCase)) + _.set(task.mermaidConfig, propertyCamelCase, value) } } - getTypedValue(value){ - if(value.toLowerCase() === 'true' || value.toLocaleString() === 'false'){ - return value === 'true' + convertPropertyToCamelCase (property) { + if (property.startsWith('kroki-diagram-options-')) { + const propertySplit = property.substring(22).split('_') + for (let i = 0; i < propertySplit.length; i++) { + const split = propertySplit[i]; + const subSplit = split.split('-') + if (subSplit.length > 1) { + for (let j = 1; j < subSplit.length; j++) { + subSplit[j] = subSplit[j].charAt(0).toUpperCase() + subSplit[j].substring(1) + } + propertySplit[i] = subSplit.join('') + } + } + return propertySplit.join('.') + } + return property + } + + getTypedValue (value) { + if (value.toLowerCase() === 'true' || value.toLocaleString() === 'false') { + return value === 'true' } - if(value.startsWith('[') && value.endsWith(']')) { - return value.substring(1,value.length - 1).split(',').map(item=>this.getTypedValue(item)) + if (value.startsWith('[') && value.endsWith(']')) { + return value.substring(1, value.length - 1).split(',').map(item => this.getTypedValue(item)) } - if(!isNaN(value)){ + if (!isNaN(value)) { return Number(value) } return value From a809503972936959ffdd1de93b93f2f50b9363f3 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Mon, 2 Jan 2023 21:49:03 +0530 Subject: [PATCH 5/8] fix: use incoming property to get value --- mermaid/src/worker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mermaid/src/worker.js b/mermaid/src/worker.js index 1397349a3..2d5e78a7f 100644 --- a/mermaid/src/worker.js +++ b/mermaid/src/worker.js @@ -71,7 +71,7 @@ class Worker { updateConfig (task, config) { for (const property in Object.fromEntries(config)) { const propertyCamelCase = this.convertPropertyToCamelCase(property) - let value = this.getTypedValue(config.get(propertyCamelCase)) + let value = this.getTypedValue(config.get(property)) _.set(task.mermaidConfig, propertyCamelCase, value) } } From b9a2a044ab8f0bd80c7206104cbda46902927b23 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Mon, 2 Jan 2023 22:00:27 +0530 Subject: [PATCH 6/8] fix: don't check for prefix as gateway server is stripping it when passed through Headers --- mermaid/src/worker.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/mermaid/src/worker.js b/mermaid/src/worker.js index 2d5e78a7f..91ff1bfbe 100644 --- a/mermaid/src/worker.js +++ b/mermaid/src/worker.js @@ -77,21 +77,18 @@ class Worker { } convertPropertyToCamelCase (property) { - if (property.startsWith('kroki-diagram-options-')) { - const propertySplit = property.substring(22).split('_') - for (let i = 0; i < propertySplit.length; i++) { - const split = propertySplit[i]; - const subSplit = split.split('-') - if (subSplit.length > 1) { - for (let j = 1; j < subSplit.length; j++) { - subSplit[j] = subSplit[j].charAt(0).toUpperCase() + subSplit[j].substring(1) - } - propertySplit[i] = subSplit.join('') + const propertySplit = property.split('_') + for (let i = 0; i < propertySplit.length; i++) { + const split = propertySplit[i]; + const subSplit = split.split('-') + if (subSplit.length > 1) { + for (let j = 1; j < subSplit.length; j++) { + subSplit[j] = subSplit[j].charAt(0).toUpperCase() + subSplit[j].substring(1) } + propertySplit[i] = subSplit.join('') } - return propertySplit.join('.') } - return property + return propertySplit.join('.') } getTypedValue (value) { From a1a464c459c9e3148703eafdf0b1be3daadd2e5b Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Tue, 3 Jan 2023 11:38:18 +0530 Subject: [PATCH 7/8] fix: lint issues --- mermaid/src/index.js | 2 +- mermaid/src/worker.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mermaid/src/index.js b/mermaid/src/index.js index da8912a57..766ef5cf5 100644 --- a/mermaid/src/index.js +++ b/mermaid/src/index.js @@ -12,7 +12,7 @@ const instance = require('./browser-instance') const server = micro(async (req, res) => { // TODO: add a /_status route (return mermaid version) // TODO: read the diagram source as plain text - const url = new URL(req.url, 'http://localhost') // create a URL object. The base is not important here + const url = new URL(req.url, 'http://localhost') // create a URL object. The base is not important here const outputType = url.pathname.match(/\/(png|svg)$/)?.[1] if (outputType) { const diagramSource = await micro.text(req, { limit: '1mb', encoding: 'utf8' }) diff --git a/mermaid/src/worker.js b/mermaid/src/worker.js index 91ff1bfbe..a267f2467 100644 --- a/mermaid/src/worker.js +++ b/mermaid/src/worker.js @@ -71,7 +71,7 @@ class Worker { updateConfig (task, config) { for (const property in Object.fromEntries(config)) { const propertyCamelCase = this.convertPropertyToCamelCase(property) - let value = this.getTypedValue(config.get(property)) + const value = this.getTypedValue(config.get(property)) _.set(task.mermaidConfig, propertyCamelCase, value) } } @@ -79,7 +79,7 @@ class Worker { convertPropertyToCamelCase (property) { const propertySplit = property.split('_') for (let i = 0; i < propertySplit.length; i++) { - const split = propertySplit[i]; + const split = propertySplit[i] const subSplit = split.split('-') if (subSplit.length > 1) { for (let j = 1; j < subSplit.length; j++) { From 980ea6257d36d002598aba73b28ee12084285ff9 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Sat, 7 Jan 2023 21:37:36 +0530 Subject: [PATCH 8/8] feat: require only `set` from lodash --- mermaid/src/worker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mermaid/src/worker.js b/mermaid/src/worker.js index a267f2467..523f167e8 100644 --- a/mermaid/src/worker.js +++ b/mermaid/src/worker.js @@ -2,7 +2,7 @@ const { logger } = require('./logger') const path = require('path') const puppeteer = require('puppeteer') -const _ = require('lodash') +const set = require('lodash/set') class SyntaxError extends Error { constructor () { @@ -72,7 +72,7 @@ class Worker { for (const property in Object.fromEntries(config)) { const propertyCamelCase = this.convertPropertyToCamelCase(property) const value = this.getTypedValue(config.get(property)) - _.set(task.mermaidConfig, propertyCamelCase, value) + set(task.mermaidConfig, propertyCamelCase, value) } }