-
-
Notifications
You must be signed in to change notification settings - Fork 47
/
kroki-client.js
78 lines (70 loc) · 2.89 KB
/
kroki-client.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
const { version } = require('../package.json')
const pako = require('pako')
const MAX_URI_DEFAULT_VALUE = 4000
const REFERER = `asciidoctor/kroki.js/${version}`
module.exports.KrokiDiagram = class KrokiDiagram {
constructor (type, format, text, opts) {
this.text = text
this.type = type
this.format = format
this.opts = opts
}
getDiagramUri (serverUrl) {
const queryParams = Object.entries(this.opts).map(([key, value]) => `${key}=${encodeURIComponent(value.toString())}`).join('&')
return `${serverUrl}/${this.type}/${this.format}/${this.encode()}${queryParams ? `?${queryParams}` : ''}`
}
encode () {
const data = Buffer.from(this.text, 'utf8')
const compressed = pako.deflate(data, { level: 9 })
return Buffer.from(compressed)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
}
}
module.exports.KrokiClient = class KrokiClient {
constructor (doc, httpClient) {
const maxUriLengthValue = parseInt(doc.getAttribute('kroki-max-uri-length', MAX_URI_DEFAULT_VALUE.toString()))
this.maxUriLength = isNaN(maxUriLengthValue) ? MAX_URI_DEFAULT_VALUE : maxUriLengthValue
this.httpClient = httpClient
const method = doc.getAttribute('kroki-http-method', 'adaptive').toLowerCase()
if (method === 'get' || method === 'post' || method === 'adaptive') {
this.method = method
} else {
console.warn(`Invalid value '${method}' for kroki-http-method attribute. The value must be either: 'get', 'post' or 'adaptive'. Proceeding using: 'adaptive'.`)
this.method = 'adaptive'
}
this.doc = doc
}
getTextContent (krokiDiagram) {
return this.getImage(krokiDiagram, 'utf8')
}
getImage (krokiDiagram, encoding) {
const serverUrl = this.getServerUrl()
const type = krokiDiagram.type
const format = krokiDiagram.format
const text = krokiDiagram.text
const opts = krokiDiagram.opts
const headers = {
Referer: REFERER,
...Object.fromEntries(Object.entries(opts).map(([key, value]) => [`Kroki-Diagram-Options-${key}`, value]))
}
if (this.method === 'adaptive' || this.method === 'get') {
const uri = krokiDiagram.getDiagramUri(serverUrl)
if (uri.length > this.maxUriLength) {
// The request URI is longer than the max URI length.
if (this.method === 'get') {
// The request might be rejected by the server with a 414 Request-URI Too Large.
// Consider using the attribute kroki-http-method with the value 'adaptive'.
return this.httpClient.get(uri, headers, encoding)
}
return this.httpClient.post(`${serverUrl}/${type}/${format}`, text, headers, encoding)
}
return this.httpClient.get(uri, headers, encoding)
}
return this.httpClient.post(`${serverUrl}/${type}/${format}`, text, headers, encoding)
}
getServerUrl () {
return this.doc.getAttribute('kroki-server-url') || 'https://kroki.io'
}
}