Skip to content

Commit

Permalink
Merge pull request #18 from chrisamti/develop
Browse files Browse the repository at this point in the history
added utf-8 support.
  • Loading branch information
adrianrudnik authored Oct 21, 2021
2 parents 043f9da + e6975f0 commit d463714
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 53 deletions.
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ ENV MJML_VALIDATION_LEVEL=soft
ENV MJML_MINIFY=true
ENV MJML_BEAUTIFY=false
ENV HEALTHCHECK=true
ENV CHARSET="utf8"
ENV DEFAULT_RESPONSE_CONTENT_TYPE="text/html; charset=utf-8"

COPY package* ./

Expand All @@ -26,4 +28,5 @@ HEALTHCHECK --start-period=10s --retries=1 CMD /healthcheck.sh || exit 1

EXPOSE 80

# ENTRYPOINT [ "node", "--inspect=0.0.0.0:9229", "index.js" ]
ENTRYPOINT [ "node", "index.js" ]
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.PHONY: docker help

UNAME_M := $(shell uname -m)
RACE=
ifeq ($(UNAME_M),x86_64)
RACE=-race
endif

all: docker ## Test, lint check and build application


docker: ## create docker images
# create arm64
docker buildx build -f Dockerfile --platform linux/arm64 --tag dndit/mjml-server:arm64 .
# create amd64
docker buildx build -f Dockerfile --platform linux/amd64 --tag dndit/mjml-server:amd64 .
# push arm64
docker push dndit/mjml-server:arm64
# push amd64
docker push dndit/mjml-server:amd64
# create multi arch manifest
# docker manifest create $(DOCKER_REGISTRY):alpine3.12-manual --amend $(DOCKER_REGISTRY):alpine3.12-arm64 --amend $(DOCKER_REGISTRY):alpine3.12-amd64
docker manifest create dndit/mjml-server --amend dndit/mjml-server:arm64 --amend dndit/mjml-server:amd64
# push
docker manifest push dndit/mjml-server

help: ## Print all possible targets
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {gsub("\\\\n",sprintf("\n%22c",""), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ MJML_VALIDATION_LEVEL "soft"
MJML_MINIFY "true"
MJML_BEAUTIFY "false"
HEALTHCHECK "true"
CHARSET="utf8"
DEFAULT_RESPONSE_CONTENT_TYPE="text/html; charset=utf-8"
```

## Development
Expand Down
118 changes: 68 additions & 50 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,95 @@
'use strict'

const express = require('express'),
bodyParser = require('body-parser'),
os = require('os'),
mjml2html = require('mjml'),
program = require('commander')
bodyParser = require('body-parser'),
os = require('os'),
mjml2html = require('mjml'),
program = require('commander')

program.usage('[options]').parse(process.argv)

const app = express()

app.use(bodyParser.text({
inflate: true,
limit: '2048kb',
type: '*/*',
inflate: true,
limit: '2048kb',
type: '*/*',
}))

const opts = {
keepComments: (process.env.MJML_KEEP_COMMENTS === 'true'),
minify: (process.env.MJML_MINIFY === 'true'),
beautify: (process.env.MJML_BEAUTIFY === 'true'),
validationLevel: (['soft', 'strict', 'skip'].includes(process.env.MJML_VALIDATION_LEVEL) ? process.env.MJML_VALIDATION_LEVEL : 'soft'),
healthchecks: (process.env.HEALTHCHECK === 'true')
keepComments: (process.env.MJML_KEEP_COMMENTS === 'true'),
minify: (process.env.MJML_MINIFY === 'true'),
beautify: (process.env.MJML_BEAUTIFY === 'true'),
validationLevel: (['soft', 'strict', 'skip'].includes(process.env.MJML_VALIDATION_LEVEL) ? process.env.MJML_VALIDATION_LEVEL : 'soft'),
healthchecks: (process.env.HEALTHCHECK === 'true')
}

const charsetOpts = {
write: (process.env.CHARSET),
contentType: (process.env.DEFAULT_RESPONSE_CONTENT_TYPE)
}

app.all('*', function (req, res) {
// enable cors
if (process.env.CORS) {
res.header('Access-Control-Allow-Origin', process.env.CORS)
res.header('Access-Control-Allow-Headers', '*')
res.header('Access-Control-Allow-Methods', 'POST')
res.header('Access-Control-Max-Age', '-1')
}

// ensure content type is set
if (!req.headers['content-type']) {
res.status(500).send('Content-Type must be set, use text/plain if unsure')
return
}

try {
const result = mjml2html(req.body || '', opts)
res.writeHead(200, { 'Content-Type': 'text/html' })
res.end(result.html)
} catch (ex) {
// print error details
console.log(req.body || '')
console.error(ex)
console.log('')

res.writeHead(400, { 'Content-Type': 'text/plain' })
res.end(ex.message)
}
// enable cors
if (process.env.CORS) {
res.header('Access-Control-Allow-Origin', process.env.CORS)
res.header('Access-Control-Allow-Headers', '*')
res.header('Access-Control-Allow-Methods', 'POST')
res.header('Access-Control-Max-Age', '-1')
}

// ensure content type is set
if (!req.headers['content-type']) {
res.status(500).send('Content-Type must be set, use text/plain if unsure')
return
}

try {
const result = mjml2html(req.body || '', opts)
if (charsetOpts.contentType != "") {
res.writeHead(200, {'Content-Type': charsetOpts.contentType})
} else {
// fall back
res.writeHead(200, {'Content-Type': 'text/html'})
}
if (charsetOpts.write != "") {
res.write(result.html, charsetOpts.write)
} else {
res.write(result.html)
}

res.end()
} catch (ex) {
// print error details
console.log(req.body || '')
console.error(ex)
console.log('')

res.writeHead(400, {'Content-Type': 'text/plain'})
res.end(ex.message)
}
})

const server = app.listen(process.env.PORT || 80)

const signals = {
'SIGHUP': 1,
'SIGINT': 2,
'SIGTERM': 15,
'SIGHUP': 1,
'SIGINT': 2,
'SIGTERM': 15,
}

const shutdown = (signal, value) => {
server.close(() => {
console.log(`app stopped by ${signal} with value ${value}`)
process.exit(128 + value)
})
server.close(() => {
console.log(`app stopped by ${signal} with value ${value}`)
process.exit(128 + value)
})
}

Object.keys(signals).forEach((signal) => {
process.on(signal, () => {
console.log(`process received a ${signal} signal`)
shutdown(signal, signals[signal])
})
process.on(signal, () => {
console.log(`process received a ${signal} signal`)
shutdown(signal, signals[signal])
})
})

console.log('self: ' + os.hostname() + ':' + server.address().port)
Expand All @@ -85,5 +101,7 @@ console.log('mjml keep comments: ' + opts.keepComments)
console.log('mjml validation level: ' + opts.validationLevel)
console.log('mjml minify: ' + opts.minify)
console.log('mjml beautify: ' + opts.beautify)
console.log('node default content-type:' + charsetOpts.contentType)
console.log('node write charset:' + charsetOpts.write)
console.log('')
console.log('POST mjml as text/plain raw body, result will be returned as text/html.')
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"body-parser": "^1.18.3",
"commander": "^2.20.3",
"express": "^4.16.3",
"mjml": "^4.10.2"
"mjml": "^4.10.3"
}
}
24 changes: 22 additions & 2 deletions test.http
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
POST http://localhost:8080/api/item
POST http://localhost:8891/api/item
Content-Type: text/html

<mjml>
Expand All @@ -7,7 +7,27 @@ Content-Type: text/html
<mj-column>
<mj-image width="100px" src="/testimage.jpg"></mj-image>
<mj-divider border-color="#F45E43"></mj-divider>
<mj-text font-size="20px" color="#F45E43" font-family="helvetica">teststring</mj-text>
<mj-text font-size="20px" color="#F45E43" font-family="helvetica">teststring zürich with umlaut</mj-text>
<mj-text font-size="20px" color="#F45E43" font-family="helvetica">Smiley: 😁</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>

###

POST http://oc4.dc-zh.eqipe.ch:8080/api/item
Host: mjml.nomad.eqipe.ch
Content-Type: text/html

<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-image width="100px" src="/testimage.jpg"></mj-image>
<mj-divider border-color="#F45E43"></mj-divider>
<mj-text font-size="20px" color="#F45E43" font-family="helvetica">teststring zürich with umlaut</mj-text>
<mj-text font-size="20px" color="#F45E43" font-family="helvetica">Smiley: 😁</mj-text>
</mj-column>
</mj-section>
</mj-body>
Expand Down

0 comments on commit d463714

Please sign in to comment.